背景
Java多线程的基础知识,如线程的启动、优先级等,网上有很多资料介绍,这里就不再赘述。这篇文章主要介绍线程的互斥以及线程的协作。
线程互斥
线程互斥又叫共享互斥,其背后的本质是JVM的内存模型,JVM内存模型本身并不非常复杂,有兴趣的同学可以自行google。理解JVM内存模型对深入理解java多线程程序有非常大的帮助。简单来说Java中的线程互斥使用关键字synchronized来实现。当一个方法使用synchronize来修饰的时候表示这个方法在一个时间段类只允许一个线程访问。synchronize既能够修饰方法,此时表示该方法为同步方法。也能够修饰语句块,此时表示该语句块为同步语句块。他们表示的含义是相同的,即表示修饰的方法或者语句块内的语句在同一时间段内,只允许一个线程访问。
线程协作
Java中线程的协作可以通过wait/notify/notifyAll以及中断的这几种方式进行,中断暂且不提,今天终点介绍wait/notify/notifyAll的含义机及其使用。
在介绍wait几个概念之前先介绍wait set即等待集合或者等待队列。在java中所有实例都有一个wait set,它是一个在执行该实例的wait方法时、操作停止的线程的集合,类似线程休息室,每个实例都有。线程进入wait
set之后除非其他线程以notify/notifyAll/interrupt唤醒或者wait到期,线程才会推出wait set。
- wait(),线程调用wait方法之后,便进入wait set。需要注意的是**想要执行wait方法,必需获取锁定,换句话说就是必需在同步语句块或者同步方法中执行,否则会抛出IllegalMonitorStateExeception的异常。**这点对于notify以及notifyAll方法而言也是一样的。
- notify(),从实例的wait set中唤醒一个线程。线程被唤醒之后便退出wait set。
- notifyAll(),从实例的wait set中唤醒所有线程,所有线程退出wait set。
在使用的时候尽可能使用notifyAll方法,避免使用notify方法。