Java线程间通信机制(等待唤醒机制)可通过wait()和notify()方法来实现。wait()方法使线程进入等待状态,而notify()方法则用于唤醒已经处于等待状态的线程。线程可以在同步块中使用wait()和notify()方法。
下面是一个生产者和消费者模型的案例代码:
消费品:
public class BaoZi {
// 包子的名称
String name;
// 包子是否存在
boolean flag;
}
消费者:
public class ChiHuo extends Thread{
/** 资源对象*/
BaoZi baoZi;
/** 定义构造方法;给线程定义名字,同事给BaoZi对象赋值*/
public ChiHuo(String threadName,BaoZi bz){
super(threadName);
this.baoZi = bz;
}
/** 吃货线程的功能:
* 如果包子不存在 线程进入等待状态
* 如果包子存在 线程开始吃包子,吃完后更改包子的状态变为不存在,唤醒包子店线程开始制作包子 */
@Override
public void run(){
String threadName = Thread.currentThread().getName();
for(int i = 0 ; i<10;i++){
synchronized (baoZi){
// 包子存在
if(baoZi.flag){
// 吃包子
System.out.println(threadName+"正在吃"+baoZi.name);
// 更改包子状态
baoZi.flag=false;
// 唤醒同一资源下的其他线程
baoZi.notify();
}else{
try{
baoZi.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
}
生产者:
public class ZaoCanDian extends Thread{
/** 资源对象*/
BaoZi baoZi;
/** 定义构造方法*/
public ZaoCanDian(String threadName,BaoZi bz){
super(threadName);
this.baoZi = bz;
}
/**早餐店线程功能:
* 如果包子存在 线程进入等待状态
* 如果包子不存在 线程开始制作包子,制作完毕更改包子状态为存在,唤醒吃货线程吃包子
*/
@Override
public void run(){
String threadName = Thread.currentThread().getName();
for(int i = 0 ; i< 10;i++){
synchronized (baoZi){
// 包子存在
if(baoZi.flag){
try{
baoZi.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}else{
System.out.println(threadName+"制作"+baoZi.name);
// 更改包子状态
baoZi.flag = true;
// 唤醒同一资源下的其它线程
baoZi.notify();
}
}
}
}
}
测试:
public class ThreaedTest {
public static void main(String[] args) {
BaoZi bz = new BaoZi();
// 包子名称
bz.name="小龙虾";
// 包子初始状态
bz.flag=false;
// 消费者名称
ChiHuo ch = new ChiHuo("猪八戒",bz);
// 生成者名称
ZaoCanDian zcd = new ZaoCanDian("春光早餐",bz);
// 启动线程
ch.start();
zcd.start();
}
}
运行结果:
简而言之,Java线程间通信机制就是一种等待被唤醒机制,它允许—个线程可以等待另一个线程完成一项任务后被唤醒。此机制由Java并发API中的0bject类提供,提供了同步方法wait()和notify(),这两个方法都需要持有当前对象的锁。wait()方法将释放锁,线程处于等待状态,直到其他线程调用notify()方法将其激活notify()方法需要持有锁,但是不会释放锁,其他线程可以获取该对象的锁。Java还提供了另一个允许多个线程按顺序等待的机制,即通过调用0bject的wait()方法,多个线程都可以被唤醒,而不仅仅是一个线程。