目录
synchronized
线程1上锁之后,线程2无法获取锁不能够执行临时区,线程2阻塞等待线程1完成释放锁之后才能够使用。可以把synchronize类比成一个房间,每次有锁的人才能够进入房间做事情,就算cpu时间片用完,只要没有这个锁那么其他线程是无法进入房间的。当用完之后就会释放锁,并且唤醒那些阻塞的线程
解决
@Slf4j
public class Test {
static int counter = 0 ;
// 定义锁对象
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() ->{
for (int i = 0; i < 5000; i++) {
synchronized (lock){ // 上锁
counter ++ ;
}
}
});
Thread t2= new Thread(() ->{
for (int i = 0; i < 5000; i++) {
synchronized (lock){
counter -- ;
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(counter);
}
}
synchonized实际上是使用对象锁保证了临界区内代码的原子性,临界区是不可分割的,不会被线程切换打断
面向对象改进
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Room room = new Room();
Thread t1 = new Thread(() ->{
for (int i = 0; i < 5000; i++) {
room.increment();
}
});
Thread t2= new Thread(() ->{
for (int i = 0; i < 5000; i++) {
room.decrement();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(room.getCounter());
}
}
class Room{
int count = 0 ;
public void increment(){
synchronized (this){
count ++ ;
}
}
public void decrement(){
synchronized (this){
count --;
}
}
public int getCounter(){
synchronized (this){
return count;
}
}
}
synchronized加在方法上
class c1{
public synchronized void test(){
}
}
class c1{
public void test(){
synchronized (this){
}
}
}
二者等价,锁住的是this对象
加载静态方法上相当于锁住类对象
线程八锁
情况1 : 1 2或者2 1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n1.b();
}).start();
}
}
@Slf4j
class Number{
public synchronized void a(){
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
}
情况2 : 1s后1 2 或 1s后2 1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n1.b();
}).start();
}
}
@Slf4j
class Number{
public synchronized void a() throws InterruptedException {
Thread.sleep(1000);
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
}
情况3 : 3 ,1s后 1 2 || 3 , 2 1s后打印1 || 2 , 3 1s后打印1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n1.b();
}).start();
new Thread(() -> {
log.debug("begin");
n1.c();
}).start();
}
}
@Slf4j
class Number{
public synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
public void c(){
log.debug("3");
}
}
情况4 : 先2,1s后打印1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n2.b();
}).start();
}
}
@Slf4j
class Number{
public synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
}
情况5 : 先2,1s后打印1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n1.b();
}).start();
}
}
@Slf4j
class Number{
public static synchronized void a() { // 锁住的是类对象
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
}
情况6 : 1s后打印1 后2 || 2 1s后打印1
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n1.b();
}).start();
}
}
@Slf4j
class Number{
public static synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public static synchronized void b(){
log.debug("2");
}
}
情况7 : 先2 1s后打印1
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n2.b();
}).start();
}
}
@Slf4j
class Number{
public static synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public synchronized void b(){
log.debug("2");
}
}
情况8 : 1s后打印1 后2 || 2 1s后打印1
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Test {
public static void main(String[] args) throws InterruptedException {
Number n1 = new Number();
Number n2 = new Number();
new Thread(() -> {
log.debug("begin");
n1.a();
}).start();
new Thread(() -> {
log.debug("begin");
n2.b();
}).start();
}
}
@Slf4j
class Number{
public static synchronized void a() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.debug("1");
}
public static synchronized void b(){
log.debug("2");
}
}










