标签:stack new t 任务 static 多线程 main cat exp appdata
概念:多线程在处理同一个资源,但是处理的动作却不相同。
为什么处理线程间通信?
多线程并发执行时,在默认情况下CPU是随机切换线程的,当我们需要多线程来共同完成一件任务,并且我们希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。
如何保证线程间通信有效利用资源?
概念:这是多线程间的协作机制。谈到线程我们经常想到的是线程间的竞争,比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制。就好比在公司里你和你的同事们,你们可能存在晋升的竞争,但更多时候你们更多是一起合作完成某些任务。
就是在一个线程金信诺过了规定操作后,就进入等待状态(wait()),等待其他线程执行完他们的指定代码过后再将其唤醒(notify());在有多个线程进行等待时,如果需要,可以使用notify All()来唤醒所有的等待线程。wait/notify就是线程间的一种协作机制。
等待唤醒中的方法:
等待唤醒机制就是解决线程间通信的问题的,使用到的3个方法的含义如下:
1、wait:线程不再活动,不再参与调度,进入wait set中,因此不会浪费cup资源,也不会去竞争锁了,这时的线程状态即是waiting。它还要等着别的线程执行一个特别的动作,就是通知(notify)在这个对象上等待的线程从wait set中释放出来,重新进入调度队列(ready queue)中。
2、notify:则选取所有通知对象的wiat set 中的一个线程释放;例如,餐馆有空位置后,等候就餐最久的顾客最先入座。
3、notifyAll:则释放所通知对象的wait set 上的全部线程。
包子类:
public class BaoZi {
    private String pi;
    private String xian;
    private boolean flag;
?
    public BaoZi() {
    }
?
    public BaoZi(String pi, String xian, boolean flag) {
        this.pi = pi;
        this.xian = xian;
        this.flag = flag;
    }
?
    public String getPi() {
        return pi;
    }
?
    public void setPi(String pi) {
        this.pi = pi;
    }
?
    public String getXian() {
        return xian;
    }
?
    public void setXian(String xian) {
        this.xian = xian;
    }
?
    public boolean isFlag() {
        return flag;
    }
?
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}
包子铺:
public class BaoZiPu implements Runnable {
    private BaoZi bz;
?
    public BaoZiPu() {
    }
?
    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }
?
    //生产包子
    @Override
    public void run() {
        int count = 0;
        while (true){
            synchronized (bz){
                //对包子的状态进行判断
                if (bz.isFlag()){
                    //包子铺调用wait方法进入等待状态,让客人吃包子
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //被唤醒之后执行,包子铺生产包子
                if (count%2==0){
                    bz.setPi("薄皮");
                    bz.setXian("三鲜");
                }else{
                    bz.setPi("厚皮");
                    bz.setXian("牛肉大葱");
                }
                count++;
                System.out.println("包子铺正在生产:"+bz.getPi()+bz.getXian()+"包子");
                //生产包子
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //包子好了后,修改状态
                bz.setFlag(true);
                bz.notify();//唤醒客人的线程
                System.out.println("包子生产完毕");
            }
        }
    }
}
客人:
public class ChiHuo implements Runnable {
    private BaoZi baoZi;
?
    public ChiHuo() {
    }
?
    public ChiHuo(BaoZi baoZi) {
        this.baoZi = baoZi;
    }
?
    public BaoZi getBaoZi() {
        return baoZi;
    }
?
    public void setBaoZi(BaoZi baoZi) {
        this.baoZi = baoZi;
    }
?
    @Override
    public void run() {
        while (true){
            synchronized (baoZi){
                if(baoZi.isFlag()==false){
                    //客人等待包子做好
                    try {
                        baoZi.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //唤醒之后,吃包子
                System.out.println("吃"+baoZi.getPi()+baoZi.getXian()+"的包子");
                baoZi.setFlag(false);//包子吃完了
                baoZi.notify();//唤醒去做包子
                System.out.println("包子吃完了");
            }
        }
    }
}
测试:
public class Demo05Main {
    public static void main(String[] args) {
        //创建包子对象
        BaoZi baoZi = new BaoZi();
?
        BaoZiPu baoZiPu = new BaoZiPu(baoZi);
        new Thread(baoZiPu).start();
        ChiHuo chiHuo = new ChiHuo(baoZi);
        new Thread(chiHuo).start();
    }
}
标签:stack new t 任务 static 多线程 main cat exp appdata
原文地址:https://www.cnblogs.com/lxy522/p/12831816.html