博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java- 简单了解线程 生产者与消费者问题(三)
阅读量:5236 次
发布时间:2019-06-14

本文共 5707 字,大约阅读时间需要 19 分钟。

  这一篇说一下生产者与消费者问题,这是操作系统里有比较经典的问题。在操作系统里生产者与消费者问题是解决进程同步问题提出来的一种方法,但在线程里同样适用。我们先来想一下,为什么要提出生产者与消费者问题?

  和操作系统一样,JAVA多线程的生产者与消费者问题一样是为解决同步而产生的,可是解决同步上一篇里面用synchronized,做一个标志位已经做到了。还要生产者和消费者问题干什么。synchronized来做到的线程同步解决不了实际上的需求,例如一家物流公司进行运货,他不可能来一件货物,他就马上叫司机把这件货物运到指定的地方。而是将一批批货物,积压到一定的需求,进行分类,然后叫司机去运这些货物。

  生产者与消费者问题,就是差不多有这么一个仓库,生产者生产货物放到这么一个仓库,仓库积压到一定的程度后再进行消费。这个是用synchronized来做一个标志位没法做到的。

  我们先来看一段程序,关于不同步的生产者与消费者带来的问题 

View Code
class Q{    String name = "none";    String sex = "none";}class Producer implements Runnable{    Q q;    Producer(Q q)    {        this.q = q;    }    public void run()    {        int i=0;        while(true)        {            if(i==0)            {                q.name = "张三";                try{ Thread.sleep(1);}                catch(Exception e){}                q.sex = "男";            }            else            {                q.name = "李静";                q.sex = "女";            }            i=(i+1)%2;                    }    }}class Consumer implements Runnable{    Q q;    Consumer(Q q)    {        this.q = q;    }    public void run()    {        while(true)        {            System.out.println(q.name+":"+q.sex);        }    }}public class test11{    public static void main(String[] args)    {        Q q = new Q();        new Thread(new Producer(q)).start();        new Thread(new Consumer(q)).start();    }}

  我们运行后发现,本来应该输出的结果都是 张三 男,结果他输出了一些结果是 张三 女

 

  用synchronized来解决生产者与消费者问题

View Code
class Q{    String name = "none";    String sex = "none";}class Producer implements Runnable{    Q q;    Producer(Q q)    {        this.q = q;    }    public void run()    {        int i=0;        while(true)        {            synchronized(q)            {                if(i==0)                {                    q.name = "张三";                    try{ Thread.sleep(1);}                    catch(Exception e){}                    q.sex = "男";                }                else                {                    q.name = "李静";                    q.sex = "女";                }                i=(i+1)%2;            }        }    }}class Consumer implements Runnable{    Q q;    Consumer(Q q)    {        this.q = q;    }    public void run()    {        while(true)        {            synchronized(q)            {                System.out.println(q.name+":"+q.sex);            }        }    }}public class test11{    public static void main(String[] args)    {        Q q = new Q();        new Thread(new Producer(q)).start();        new Thread(new Consumer(q)).start();    }}

  真正解决生产者与消费者问题的写法

View Code
class Q{    String name = "none";    String sex = "none";        boolean bFull = false;}class Producer implements Runnable{    Q q;    Producer(Q q)    {        this.q = q;    }    public void run()    {        int i=0;        while(true)        {            synchronized(q)            {                if(q.bFull)                    try{ q.wait(); } catch( Exception e){}                if(i==0)                {                    q.name = "张三";                    try{ Thread.sleep(1);}                    catch(Exception e){}                    q.sex = "男";                }                else                {                    q.name = "李静";                    q.sex = "女";                }                i=(i+1)%2;                                //装完后                q.bFull = true;                q.notify();                            }        }    }}class Consumer implements Runnable{    Q q;    Consumer(Q q)    {        this.q = q;    }    public void run()    {        while(true)        {            synchronized(q)            {                if(!q.bFull)                    try{ q.wait(); } catch( Exception e){}                System.out.println(q.name+":"+q.sex);                                //输出出来                q.bFull = false;                q.notify();            }        }    }}public class test11{    public static void main(String[] args)    {        Q q = new Q();        new Thread(new Producer(q)).start();        new Thread(new Consumer(q)).start();    }}

  这里使用了wait和notify两个方法。他的思路过程是这样的:在生产者里判断bFull是否为true,如果他是true说明消费者正在消费,那么生产者等待,否则他开始生产,生产到一定程度后,他将bFull设为true并使用notify方法通知消费者他生产完了,消费者收到通知后,也判断bFull是否为true,如果是那么他开始消费,消费完毕后他通知生产者,他消费完了,你又可以再开始生产了。

  使用面向对象的方式来进一步写生产者与消费者问题

 

class Q{    private String name = "none";    private String sex = "none";    private boolean bFull = false;        public synchronized void put(String name,String sex)    {        if(bFull)            try{ wait(); } catch( Exception e){}        this.name = name;        try{ Thread.sleep(1); } catch( Exception e){}        this.sex = sex;                bFull = true;        notify();    }        public synchronized void get()    {        if(!bFull)            try{ wait(); } catch( Exception e){}        System.out.println(name+":"+sex);            bFull =  false;        notify();    }}class Producer implements Runnable{    Q q = null;    public Producer(Q q)    {        this.q = q;    }    public void run()    {        int i=0;        while(true)        {            if(i==0)            {                q.put("张三","男");            }            else            {                q.put("李四","女");            }            i=(i+1)%2;        }    }}class Consumer implements Runnable{    Q q;    public Consumer(Q q)    {        this.q = q;    }    public void run()    {        while(true)        {            q.get();        }    }}public class test11{    public static void main(String[] args)    {        Q q = new Q();        new Thread(new Producer(q)).start();        new Thread(new Consumer(q)).start();    }}

 

 

 

  讲的不清楚,更多是写给自己看的笔记,详细了解可以去看:《JAVA就业教程》

 

转载于:https://www.cnblogs.com/cxeye/archive/2012/09/11/2680007.html

你可能感兴趣的文章
微软Azure运营方世纪互联遭做空后强劲反弹
查看>>
根据经纬度算距离
查看>>
(组件、路由)懒加载
查看>>
《C++反汇编与逆向分析技术揭秘》之十——构造函数
查看>>
lightoj 1057 - Collecting Gold(状压dp)
查看>>
关于restful开发的疑惑
查看>>
什么是Reactor模式,或者叫反应器模式
查看>>
高效程序员的工作场所和装备
查看>>
Windbg+Procdump解决w3wp.exe CPU过百问题
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>
解决php -v查看到版本与phpinfo()版本不一致问题
查看>>
在线制作logo
查看>>
Java反射之修改常量值
查看>>
jmeter远程分布执行遇到的网卡坑(A Test is currently running,stop or ....)
查看>>
Xcode 中设置部分文件ARC支持
查看>>
iOS-解决iOS8及以上设置applicationIconBadgeNumber报错的问题
查看>>
亡灵序曲-The Dawn
查看>>