1. synchronized 同步方法
a.、方法内部的变量是线程安全的,它属于方法的私有变量
b、 synchronized声明的方法一定是排队运行的。(一般情况下只有共享资源的读写才需要同步化)
c、synchronized声明在方法上时,线程锁的是当前对象。
d、synchronized的锁重入功能
一个线程得到对象锁之后,再次请求对象锁时,是可以再次得到该对象锁的。
eg:synchronized修饰一个类中的A、B两个方法,当线程X获得对象锁后开始调用A方法,并且在A方法内部调用B方法,此时是可以调用B方法的,如果不能调用会造成死锁。(ps:存在子父类关系时,子类可以通过‘可重入锁’调用父类的同步方法)
e、出现异常时,线程持有的锁会自动释放。
2. synchronized 同步语句块
a、synchronized声明方法的弊端:如果同步方法的执行时间过长,会影响其他线程的调用,因为它锁的是对象。
b、synchronized(this)即:将当前对象作为锁,效果等同于synchronized声明方法。两者都会对同步方法和同步代码块呈阻塞状态
c、synchronized(非this对象 X) 例如将map作为锁对象,同一时间只允许一个线程执行synchronized(map)的代码块
synchronized(非this对象 X) 小结:它是将x对象作为‘对象监视器’,即:x为同步锁
1)、当多个线程同时调用syn(x)代码块时,会呈现同步效果
2)、当其他线程执行x对象内部的同步方法时,呈现同步效果
3)、当其他线程执行x对象内部的syn(this)代码块时,呈现同步效果
4)、当其他线程调用非同步方法时,是异步的
5)、当其他线程调用syn(y)的代码块时,是异步的
d、synchronized声明在静态方法上时,其等同于synchronized(this.class),表示给class类上锁。[syn(Class)和syn(this)是异步执行的,因为他们的对象监视器不同]
e、synchronized(String str)注意事项:
由于JVM具有对string常量池缓存的功能,例如:String a = "flg" ; String b = "flg" a == b (true)
100%会导致原设计为异步的代码块出现同步效果。例如 : syn(a){...} syn(b){...} a、b都指向常量池中的同一个String对象,所以会出现同步效果
3. 死锁
即:两个线程互相持有对方的锁。
代码描述:
synchronized(lock1){... synchronized(lock2){...}}
synchronized(lock2){... synchronized(lock1){...}}