1.1 线程间通信
**概念 :**多个线程在处理同一个资源,但是处理的线程任务不一样
比如说:荒木老师生产小面包,而Dio来吃面包 ,这个面包就是同一个资源,
然而 一个是生产 一个是吃,那么荒木老师和Dio之间就存在线程通信的问题。
当多个线程并发执行时,我们的CPU进行高速的切换随即切换线程。但是我们要做多个线程来完成同一个任务的时候,那么多线程之间需要一些协调通信。这就是为什么我们要处理线程之间的通信。
并且, 多个线程在操作同一份数据的时候,为了避免对同一共享变量的争夺,(自我理解:荒木老师在没有生产出小面包的时候 Dio就要吃)。
通过一定的手段使各个线程能有效的利用资源 这种手段叫做 等待唤醒机制。
1.2 等待唤醒机制
因为不想再改面包 所以我们就让Dio吃包子吧
//包子属性
class BaoZi{
/*
* 有皮
* 有馅
* 对包子状态的判断
* */
String xian;
String pi;
boolean flag=false;
}
//消费者
class Consumer implements Runnable{
private BaoZi baoZi;
private Lock lock; //锁对象
public Consumer(BaoZi baoZi, Lock lock) {
this.baoZi = baoZi;
this.lock = lock;
}
@Override
public void run() {
while (true){
synchronized (lock){
//判断有没有包子 (没有包子)
if (baoZi.flag==false){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("开始吃"+this.baoZi.pi+this.baoZi.xian+"的包子");
//吃完包子后修改状态
baoZi.flag=false;
//吃完唤醒包子铺线程,生产包子 (饿了 ,来唤醒生产者)
lock.notify();
System.out.println("吃完了"+this.baoZi.pi+this.baoZi.xian+"的包子");
System.out.println("============================================");
}
}
}
}
//生产者
class Producer implements Runnable{
private BaoZi baoZi;
private Lock lock;
public Producer (BaoZi baoZi, Lock lock) {
this.baoZi = baoZi;
this.lock = lock;
}
@Override
public void run() {
int count=0;
//让包子铺一直做包子
while (true){
synchronized (lock){
//首先判断有没有包子 (一开始没有包子)
if (baoZi.flag){
try {
lock.wait(); //等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// wait之后的代码被消费者唤醒后执行,包子铺生产包子
if (count%2==0){
baoZi.pi="薄皮";
baoZi.xian="牛肉大葱";
}else {
baoZi.pi="冰皮";
baoZi.xian="韭菜鸡蛋";
}
count++;
System.out.println("正在做"+baoZi.pi+baoZi.xian+"馅的包子");
//包子正在做
try {
System.out.println("做包子中························");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.baoZi.flag=true;
//唤醒吃包子的消费者
lock.notify();
System.out.println("做好了"+baoZi.pi+baoZi.xian+"馅的包子");
}
}
}
}
//主方法
public class P_CThreadTest {
public static void main(String[] args) {
BaoZi baoZi = new BaoZi();
Lock lock = new ReentrantLock();
new Thread(new Producer(baoZi,lock)).start();
new Thread(new Consumer(baoZi,lock)).start();
}
}