• Java线程间通信--生产者消费者





    class ProducerConsumerDemo
    {
        public static void main(String[] args)
        {
            Resource r = new Resource();

            Producer pro = new Producer(r);
            Consumer con = new Consumer(r);

            Thread t1 = new Thread(pro);
            Thread t2 = new Thread(pro);
            Thread t3 = new Thread(con);
            Thread t4 = new Thread(con);

            t1.start();
            t2.start();
            t3.start();
            t4.start();

        }
    }

    /*
    需求:我不想仅仅是两个线程这样同步,我需要很多线程抢资源
    这样更快
    但出现了问题:这时候线程不遵循你一我一的规律了,直接出错
    为什么?
    由于线程在wait的地方等待执行,是不需要再次判断条件的

    死锁:全部线程都冻结了

    怎么做?
    重复判断等待条件+全部唤醒

    */



    /*
    对于多个生产者和消费者。
    为什么要定义while判断标记。
    原因:让被唤醒的线程再一次判断标记。


    为什么定义notifyAll,
    因为需要唤醒对方线程。
    因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。

    */


    class Resource
    {
        private String name;
        private int count = 1;
        private boolean flag = false;                         /*资源空间的标记,同步的时候必须用到*/
                //  t1    t2
        public synchronized void set(String name)
        {
            while(flag)                                                      /*我需要下面的语句执行完再判断循环条件,就这样做*/
                try{this.wait();}catch(Exception e){}//t1(放弃资格)  t2(获取资格)    /*冻结在这里的,是不需要再次判断条件的,直接运行,没有冻结的需要再次判断条件*/
            this.name = name+"--"+count++;

            System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
            flag = true;
            this.notifyAll();             /*notify往往唤醒线程中的第一个*/
        }


        //  t3   t4  
        public synchronized void out()
        {
            while(!flag)                           
                try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)          
            System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
            flag = false;
            this.notifyAll();                                     /*把全部线程唤醒才可以,相当于整体一的思想,全部唤醒,那么这个线程重复判断条件后,就再次冻结*/
        }
    }

    class Producer implements Runnable
    {
        private Resource res;

        Producer(Resource res)
        {
            this.res = res;
        }
        public void run()
        {
            while(true)
            {
                res.set("+商品+");
            }
        }
    }

    class Consumer implements Runnable
    {
        private Resource res;

        Consumer(Resource res)
        {
            this.res = res;
        }
        public void run()
        {
            while(true)
            {
                res.out();
            }
        }
    }

  • 相关阅读:
    【DFS】算24点
    【位运算】【BFS】移动玩具
    【并查集】【DFS】搭桥
    shell脚本编写informix数据库中表的导入和导出
    利用springloaded进行java jar&class的动态替换
    利用springloaded进行java class动态替换
    ActiveMq unsupported major.minor version 52.0
    oracle主键修改&设置某一字段可以为null
    XStream将XML转javaben,出现多余的tag,导致出错
    oracle:the password has expired
  • 原文地址:https://www.cnblogs.com/liangqiyuan/p/5664856.html
Copyright © 2020-2023  润新知