线程通信
传统的线程通信
用synchonized同步的情况下,可以使用Object的三个方法:
- wait():释放同步监视器,直到其他线程调用该同步监视器的notify()或notifyAll()方法
- notify():唤醒此同步监视器上等待的单个线程(如有多个等待,随便唤醒一个)
- notifyAll():唤醒此同步监视器上的所有线程
使用Condition控制线程通信
用Lock对象同步的情况下:
用Condition类完成线程通信。其实和传统的线程通信方式类似,这里的Condition类比于同步监视器。
Condition接口提供的实例方法如下(类比于上面的Object提供的三个方法,功能一样):
Lock类提供获得Condition对象的方法:
具体代码实例参看《疯狂Java讲义(第四版)》757页~758页
使用阻塞队列(BlockingQueue)控制线程通信
当生产者试图向BlockingQueue中放入元素时,如果队列已满,则该线程被阻塞;当消费者线程试图从BlockingQueue中取出元素时,如果队列已空,则该线程被阻塞。
BlockingQueue接口继承了Queue接口,提供了普通队列有的方法add,remove,peek等,可使用该队列的实现类ArrayBlockingQueue。
具体实例代码见《疯狂Java讲义(第四版)》760~761页。
线程组和未处理的异常
线程池
系统启动一个新线程的成本是比较高的,因为涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短的线程时,更应该考虑使用线程池。
线程池在线程启动时即创建大量空闲的线程,程序将一个Runnable对象或Callable对象传给线程池,线程池会启动一个空闲的线程池来执行他们的run方法或call方法,当run方法或call方法执行结束后,该线程并不会死亡,而是再次返回线程池中变为空闲状态,等待下一个Runnable对象的run或call方法。
ThreadLocal类
ThreadLocal将需要并发访问的资源复制多份,每个线程拥有一份资源(当然不需要对变量同步),隔离了多个线程之间的共享冲突。
而线程同步机制就是为了多个线程共享资源的,和ThreadLocal解决问题本身就不一样。