synchronized又叫暗锁,同步锁,用于保证线程共享资源的安全。
synchronized用法
1,用于实例方法中
这个时候需要使用一个对象。如果new了多个对象,那么无法实现同步。
其他对象不能获取被synchronized锁定的方法。但是可以获得其他未被锁定的方法
2,用于同步块中
需要创建一个对象锁,
一个线程持有此处对象锁时,其他线程不可以获得,进入阻塞状态。
相比较于实例方法,提高了性能
3,用于静态方法
当synchronized作用于静态方法时,其锁就是当前类的class对象锁。
注意:当线程a调用一个实例中被synchronized修饰的静态方法时
,线程b想要调用这个实例中被synchronized修饰的实例方法是可以的。
这个实例方法是占用的是当前的实例对象锁。不冲突。
但是加锁的时候还是会冲突
synchronized具有可重入性
即一个锁在使用时可以再次进入调用其他方法。
sleep
sleep方法暂停当前线程后,会进入阻塞状态,
只有当睡眠时间到了,才会转入就绪状态。
而yield方法调用后 ,是直接进入就绪状态,
所以有可能刚进入就绪状态,又被调度到运行状态。
wait
线程会被暂停,锁会被释放,知道有线程调用notify或者notifyall的时候才会继续执行。notify和notifyall也不会立刻释放,等到synchronized锁里的运行完才会释放。
yield
yield会将方法立刻进入就绪状态,可能立刻就执行,也有可能让步·。
sleep方法比yield方法有更好的可移植性,通常不要依靠yield方法来控制并发线程的执行。
Wait,notify,notifyall,被定义在object类中
要在synchronized修饰的方法/块下使用
这些方法在使用时,必须要标明所属的锁,而锁又可以是任意对象。
能被任意对象调用的方法一定定义在Object类中
join
Join()
例:在线程A里调用了线程B.join(),则线程A运行到此处时被阻塞,
等到线程B死亡时,线程A开始执行
。假如,线程B之前还有其他被调用的线程,则不会被阻塞。
Join的底层是wait,join方法是一个同步方法
,当线程B.join进入时,线程A获得B的锁,然后调用了wait方法,被挂起等待。
等线程B死亡时,会被自动notifyall,释放锁
如果有多个线程是wait,那么notify只能随机解除一个线程。如果要具体控制线程,那么需要lock的condition的来控制。