1,lock的可重入性
synchronized的这种锁定方式是可重入(reentrant)的,即:
- 如果当前线程已经拥有对象的monitor,则接下来的各种调用如果包含对该对象的monitor请求拥有的synchronized代码均能不堵塞地继续执行
- 一旦离开synchronized的代码段范围外,锁定(对象的monitor的拥有权)即被解除。
2,线程安全与性能
任何线程安全的方案均有性能的损耗,synchronized的方法在早期的JVM实现中非常的低效,即使现在也和和普通函数调用开销相差好几倍到十几倍,而且synchronized的方法只能有一个线程执行,对于有很多cpu的机器来说是一种很大的浪费。
目前synchronized的在某些场合的替代方案有:
- copy on write
- compare and set
3,wait,notify和notifyAll
wait,notify和notifyAll都是超类Object的成员方法,意味着任何对象都有这三个方法。下表给出这3个方法的功能说明
| wait
| 等待对应对象的notify(或notifyAll)事件或者超时发生,该方法必须在拥有对应对象monitor的时候调用,调用后将堵塞直到对应对象的notify(或notifyAll)事件或者超时发生,在堵塞期间,当前线程自动放弃对应对象的monitor,
| |
| notify | 唤醒一个调用对应对象wait()方法的线程。如果有多个线程处于wait状态,则随机唤醒任意一个线程,该方法必须在拥有对应对象monitor的时候调用 | |
| notifyAll | 和notify不同的是,该方法唤醒所有对应调用对应对象wait()方法的线程。
|
排队拿号买饼的例子,窗口等价于对象的monitor,notify等价于叫号,wait等价于等待被叫号。
另外,Java 5的JDK中新增了并发包(java.util.concurrent),大大简化了并发程序的开发,这将在以后的文章中予以介绍。




