Thread之线程通信(wait和notify)
线程通信的定义
线程是程序中独立的个体,但这些个体如果不经过处理就不能成为一个整体。线程间的通信就是使它们成为整体的方案之一。
 可以说通过线程通信,线程之间的交互性会更强大,能够大大提高CPU的复用率,同时也可以对线程任务进行有效的把控和监督
轮询实现
import lombok.SneakyThrows;
import java.util.ArrayList;
import java.util.List;
/**
 * 模拟厨师与服务员上菜
 * @author layman
 * @date 2021/2/7
 */
public class Demo10 {
    public static void main(String[] args) {
        Cook cook = new Cook();
        WaiterA threadA = new WaiterA(cook);
        threadA.start();
        WaiterB threadB = new WaiterB(cook);
        threadB.start();
    }
}
class Cook {
    //强制线程从公共堆栈获取数据
    public volatile List<Integer> meal = new ArrayList();
    public void add() throws InterruptedException {
        for (int i = 1; i < 8 ; i++) {
            meal.add(i);
            System.out.println("第 "+i+" 道菜做好了");
            Thread.sleep(1000);
        }
    }
}
class WaiterA extends  Thread{
    private Cook cook;
    public WaiterA(Cook cook){
        this.cook = cook;
    }
    @SneakyThrows
    @Override
    public void run() {
        while (true){
            cook.add();
        }
    }
}
class WaiterB extends  Thread{
    private Cook cook;
    public WaiterB(Cook cook){
        this.cook = cook;
    }
    @SneakyThrows
    @Override
    public void run() {
        while (true){
            if(cook.meal.size() == 5){
                System.out.println("1号桌5个菜已经做好了,准备上菜");
                throw new InterruptedException();
            }
        }
    }
}
运行结果
 
结论

wait和notify实现

 重点 : wait()会释放对象锁
wait方法
/**
 * 测试wait()只能在同步方法中调用
 */
public class TestWait {
    private String name = "layman";
    public void methodA() throws InterruptedException{
            name.wait();
    }
    public void methodB() throws InterruptedException {
        synchronized (name){
            name.wait();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        TestWait tw = new TestWait();
        tw.methodA();  //Exception in thread "main" java.lang.IllegalMonitorStateException
     // tw.methodB();
    }
}
nofify方法

import lombok.SneakyThrows;
public class Demo12 {
    public static void main(String[] args) throws InterruptedException {
        Object obj = new Object();
        Demo12ThreadA threadA = new Demo12ThreadA(obj);
        threadA.start();
        //让主线程等待2秒钟
        Thread.sleep(2000);
        Demo12ThreadB threadB = new Demo12ThreadB(obj);
        threadB.start();
    }
}
class Demo12ThreadA extends  Thread{
    private Object lock;
    public  Demo12ThreadA(Object lock){
        setName("A线程");
        this.lock = lock;
    }
    @SneakyThrows
    @Override
    public void run() {
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+"进入等待,时间为:"+System.currentTimeMillis());
            lock.wait();
            System.out.println(Thread.currentThread().getName()+"结束等待,时间为:"+System.currentTimeMillis());
        }
    }
}
class Demo12ThreadB extends  Thread{
    private Object lock;
    public  Demo12ThreadB(Object lock){
        setName("B线程");
        this.lock = lock;
    }
    @SneakyThrows
    @Override
    public void run() {
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+"进行通知,时间为:"+System.currentTimeMillis());
            lock.notify();
            Thread.sleep(1000);
        }
    }
}
结论
- wait()会立刻释放对象锁,自身进入等待状态
- notify()不会立刻释放对象锁,当同步代码块执行完毕后才会释放
![在这里插入图片描述]() 
![在这里插入图片描述]() 
补充说明
sleep(long millis)与wait(long timeout)的区别:sleep不会释放对象锁,而wait会
 
                    
                


 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号