1、synchronized锁住的是括号里的对象,而不是代码
2、当synchronized锁住一个对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的
3、可以锁什么?
3.1、this:也就是当前对象,由于多线程下,创建的某各类的对象在堆中不是同一个,所以锁失效
3.2、类名.class:也就是某一类对象,例如Person类,那么当Person类被锁,只要是该类创建的所有对象,就都是互斥的
4、使用代码讲解这两种方式的区别
```
package com.xc.test.synchron;
public class Settle {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
Settle settle = new Settle();
settle.method();
});
Thread thread2 = new Thread(() -> {
Settle settle = new Settle();
settle.method();
});
thread1.start();
thread2.start();
}
public void method(){
System.out.println("锁定前的代码" + Thread.currentThread());
synchronized (this) {
System.out.println("第一个线程进来之后,需要等待执行完毕,后续的线程才能进来" + Thread.currentThread());
try {
Thread.sleep(90000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("锁定后的代码" + Thread.currentThread());
}
}
```
输出结果
```
锁定前的代码Thread[Thread-0,5,main]
锁定前的代码Thread[Thread-1,5,main]
第一个线程进来之后,需要等待执行完毕,后续的线程才能进来Thread[Thread-0,5,main]
第一个线程进来之后,需要等待执行完毕,后续的线程才能进来Thread[Thread-1,5,main]
```
```
package com.xc.test.synchron;
public class Settle {
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
Settle settle = new Settle();
settle.method();
});
Thread thread2 = new Thread(() -> {
Settle settle = new Settle();
settle.method();
});
thread1.start();
thread2.start();
}
public void method(){
System.out.println("锁定前的代码" + Thread.currentThread());
synchronized (Settle.class) {
System.out.println("第一个线程进来之后,需要等待执行完毕,后续的线程才能进来" + Thread.currentThread());
try {
Thread.sleep(90000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("锁定后的代码" + Thread.currentThread());
}
}
```
```
锁定前的代码Thread[Thread-0,5,main]
锁定前的代码Thread[Thread-1,5,main]
第一个线程进来之后,需要等待执行完毕,后续的线程才能进来Thread[Thread-0,5,main]
```
5、总结
从控制台打印出来的结果可以看出,分别锁住this和类的class对象,结果存在天差地别,前者没有锁住,后者才锁住了