什么是线程通信、如何实现
所谓线程通信就是线程间相互发送数据,线程间共享一个资源即可实现线程通信。
线程通信常见形式
1.通过共享一个数据的方式实现;
2.根据共享数据的情况决定自己该怎么做,以及通知其他线程怎么做;
线程通信实际应用场景
生产者与消费者模型:生产者线程负责生产数据,消费者线程负责消费生产者产生的数据。
生产者线程生产完数据后唤醒消费者,然后等待自己,消费者消费完该数据后唤醒生产者,然后等待自己。
线程通信的前提
线程通信通常是在多个线程操作同一个共享资源的时候需要进行通信,且要保证线程安全。
Object类的等待和唤醒方法
方法 | 说明 |
---|---|
void wait() | 让当前线程等待并释放所占锁,直到另一个线程调用notify()方法或 notifyAll()方法 |
void notify() | 唤醒正在等待的单个线程 |
void notifyAll() | 唤醒正在等待的所有线程 |
注意
上述方法应该使用当前同步锁对象进行调用。
建议阅读:Java线程同步:synchronized、Lock锁
代码示例
public class TestDemo {
public static void main(String[] args) {
// 1、生产者线程:负责不断接收打进来的电话
CallThread call = new CallThread();
call.start();
// 2、消费者线程:客服,每个客服每次接听一个电话
ReceiveThread r1 = new ReceiveThread();
r1.start();
}
}
public class CallThread extends Thread{
@Override
public void run() {
// 不断的打入电话
while (true){
CallSystem.call();
}
}
}
public class ReceiveThread extends Thread{
@Override
public void run() {
// 1号 2号
while (true){
CallSystem.receive();
}
}
}
public class CallSystem {
// 定义一个变量记录当前呼入进来的电话。
public static int number = 0; // 最多只接听一个。
/* 接入电话
*/
public synchronized static void call() {
try {
number++;
System.out.println("成功接入一个用户,等待分发~~~~");
// 唤醒别人 : 1个
CallSystem.class.notify();
// 让当前线程对象进入等待状态。
CallSystem.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
分发电话
*/
public synchronized static void receive() {
try {
String name = Thread.currentThread().getName();
if(number == 1){
System.out.println(name + "此电话已经分发给客服并接听完毕了~~~~~");
number--;
// 唤醒别人 : 1个
CallSystem.class.notify();
CallSystem.class.wait(); // 让当前线程等待
}else {
// 唤醒别人 : 1个
CallSystem.class.notify();
CallSystem.class.wait(); // 让当前线程等待
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}