A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

import java.util.concurrent.locks.*;

class goods
{
        int num=0;
        String name;
        boolean flag=false;
        public void set(String name)
        {
                this.name=name;
                num++;
                System.out.println(Thread.currentThread().getName()+"生产第"+num+"件"+name);
        }
        public void show()
        {
                System.out.println(Thread.currentThread().getName()+"消费第"+num+"件"+name);
        }
}

class Producer implements Runnable
{
        Lock lock=new ReentrantLock();
        Condition condition=lock.newCondition();
        goods g;
        Producer(goods g)
        {
                this.g=g;
        }
        public void run()
        {
                lock.lock();
                while(true)
                {
                        try
                        {
                                while(g.flag)
                                        condition.await();
                                if(g.flag)                       
                                g.set("商品");
                                g.flag=true;
                                condition.signalAll();
                        }
                        finally
                        {
                                lock.unlock();
                        }
                }
        }
}

class Customer implements Runnable
{
        goods g;
        Lock lock=new ReentrantLock();
        Condition condition=lock.newCondition();
        Customer(goods g)
        {
                this.g=g;
        }
        public void run()
        {
                lock.lock();
                while(true)
                {
                        try
                        {
                                while(!g.flag)
                                        condition.await();
                                if(g.flag)                       
                                g.set("商品");
                                g.flag=false;
                                condition.signalAll();
                        }
                        finally
                        {
                                lock.unlock();
                        }
                }
               
        }
}

class ProducerCustomer
{
        public static void main(String[] args)
        {
                goods g=new goods();
                new Thread(new Producer(g)).start();
                new Thread(new Customer(g)).start();
        }
}

7 个回复

倒序浏览
我帮你找个小问题,你卖东西了吗?其他的自己好好调试调试,我就不帮你了
回复 使用道具 举报
首先是异常处理  有重大错误, catch 是必须有的,一个或者多个。没有catch 怎么处理异常呢?
其他应该没什么问题。
回复 使用道具 举报
缺少catch (InterruptedException e){} 而且整个代码不完整,都没法给你调  
回复 使用道具 举报
本帖最后由 ۩大世界小人物 于 2014-5-17 21:08 编辑
  1. <p>package testSingle;</p><p>import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;</p><p>/*
  4. * 生产者和消费者:
  5. *
  6. * jdk1.5以后将同步和锁封装成了对象。并将操作锁的隐式方式定义到了该对象中。将隐式动作变成了显示动作。*******************
  7. */</p><p>class Resrouce
  8. {
  9. private String name;
  10. private int count = 1;
  11. private boolean flag = false;

  12. Lock lock = new ReentrantLock();//定义一把锁

  13. //通过已有的锁  获取该锁上的监视器对象。
  14. Condition con = lock.newCondition();

  15. public void set(String name)
  16. {
  17.   lock.lock();//获取一把锁
  18.   
  19.   try
  20.   {
  21.    while(flag)
  22.    {
  23.     try
  24.     {
  25.      con.await();
  26.     }
  27.     catch (InterruptedException e)
  28.     {
  29.      // TODO: handle exception
  30.     }
  31.    }
  32.      
  33.    this.name = name + count;
  34.    count++;
  35.    System.out.println(Thread.currentThread().getName()+"....生产者。。。。"+this.name);
  36.    flag = true;
  37.    
  38.    con.signalAll();
  39.   }
  40.   catch (Exception e)
  41.   {
  42.    // TODO: handle exception
  43.   }
  44.   finally
  45.   {
  46.    lock.unlock();
  47.   }
  48.   
  49. }

  50. public  void out()
  51. {
  52.   lock.lock();//获取锁
  53.   
  54.   try
  55.   {
  56.    while(!flag)
  57.    {
  58.     try
  59.     {
  60.      con.await();
  61.     }
  62.     catch (InterruptedException e)
  63.     {
  64.      // TODO: handle exception
  65.     }
  66.    }
  67.    
  68.    System.out.println(Thread.currentThread().getName()+"-----------------消费者-"+ this.name);
  69.    
  70.    flag = false;
  71.    
  72.    con.signalAll();   
  73.   }
  74.   catch (Exception e)
  75.   {
  76.    // TODO: handle exception
  77.   }
  78.   finally
  79.   {
  80.    lock.unlock();
  81.   }
  82.   
  83. }
  84. }
  85. //生产者
  86. class Producer implements Runnable
  87. {
  88. private Resrouce r;
  89. Producer(Resrouce r)
  90. {
  91.   this.r = r;
  92. }</p><p> @Override
  93. public void run()
  94. {
  95.   // TODO Auto-generated method stub
  96.   while(true)
  97.    r.set("馒头");
  98. }
  99. }
  100. //消费者
  101. class Consumer implements Runnable
  102. {
  103. private Resrouce r;
  104. Consumer(Resrouce r)
  105. {
  106.   this.r = r;
  107. }</p><p> @Override
  108. public void run()
  109. {
  110.   // TODO Auto-generated method stub
  111.   while(true)
  112.    r.out();
  113. }
  114. }
  115. public class ResourceTest
  116. {</p><p> /**
  117.   * @param args
  118.   */
  119. public static void main(String[] args)
  120. {
  121.   // TODO Auto-generated method stub
  122.   Resrouce r = new Resrouce();
  123.   Consumer c1 = new Consumer(r);
  124.   Consumer c2 = new Consumer(r);
  125.   
  126.   Producer p1 = new Producer(r);
  127.   Producer p2 = new Producer(r);
  128.   
  129.   
  130.   Thread t1 = new Thread(p1);
  131.   t1.start();
  132.   Thread t2 = new Thread(p2);
  133.   t2.start();
  134.   Thread t3 = new Thread(c1);
  135.   t3.start();
  136.   Thread t4 = new Thread(c2);
  137.   t4.start();</p><p> }</p><p>}</p><p>



  138. </p>
复制代码


可以对照一下这个消费者线程安全问题

点评

谢谢。支持  发表于 2014-5-17 20:45
回复 使用道具 举报 1 0
本帖最后由 pandapan 于 2014-5-17 21:28 编辑

这位同学,应该是刚接触java吧。下面我把这个里面的存在的目前发现的问题列举出来
1. 你的这段代码应该是没有编译过的吧,或者说只是用UE或者EditPlus编写的,一般情况下我们是不直接写try finally代码的,这样是完全没有异常处理的代码的,那么就算有异常,我们是怎么发现的呢?
2. 类的命名不符合规则,货物类单词拼写的是对的,goods,但是记得要大写的,童鞋。应该是Goods(不要小瞧这些细节,面试的时候,假如面试官看你写这样的代码,会很生气的,因为有通用的规则,大家都是遵守的,凭什么我们例外的?)
3.需求理解有一定的偏差,或者说理解了需求,实现的有偏差。通过浏览你的代码,我是否可以反推出这样的需求呢?
3.1 业务背景
       在日常生活中呢,很普通的一个事情就是生产者和消费者的故事了,生产者负责生产,消费者负责消费,生产和消费的是随机的,就是生产者生产一个后,便开始停工,等着消费者完成后再继续生产。请模拟这样的过程。
3.2 需求分析
      看到这个问题,我们分析的结果如下,生产者呢,负责生产商品,消费者呢,负责消费商品,这是不同的操作,却要同时进行,因而考虑使用多线程,在取的过程和消费的过程可能会发生冲突,因而考虑到要加锁。这是大概的设计。由于生产者生产了一个后,便停用,等着消费者消费,便没有商品的多少和商品的队列的信息的维护,我们用一个标记(Flag)描述即可.3.3 设计(这里的设计我就不怎么说了,因为楼主设计的整体思路应该是有的,但是感觉是缺乏基本知识的理解)
  设计呢,首先便要知道多线程的基本知识,
(1)在不同的线程中加锁呢,要加同样的锁,如果锁不同的话,那么加锁就没有意义了,楼主这里在生产者和消费者中使用了不同的锁,因为都是在自己的类中创立的,因而有Lock创建的Condition肯定也是有问题的。
你的代码我进行了如下的改进,可以运行了,希望能够帮到你.希望楼主能够先学习学习同步代码块的知识,这样再学习Lock和Condition的知识会很快的。
  1. import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;

  4. public class ProducerCustomer {

  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 Goods good = new Goods();
  8.                 new Thread(new Consumer(good)).start();
  9.                 new Thread(new Producer(good)).start();
  10.         }
  11. }


  12. /**
  13. * 生产者
  14. * @author Panda
  15. *
  16. */
  17. class Producer implements Runnable{
  18.         Goods good = null;
  19.         public Producer(Goods good){
  20.                 this.good = good;
  21.         }
  22.         @Override
  23.         public void run() {
  24.                 // TODO Auto-generated method stub
  25.                 while(true){
  26.                         LockInstance.lockEg.lock();
  27.                         try {
  28.                                 while(good.flag){//true的时候不生产
  29.                                         LockInstance.proCondtion.await();
  30.                                 }
  31.                                 good.set("商品");
  32.                                 good.flag = true;
  33.                                 LockInstance.conCondtion.signal();
  34.                         } catch (InterruptedException e) {
  35.                                 e.printStackTrace();
  36.                         }finally{
  37.                                 LockInstance.lockEg.unlock();
  38.                         }
  39.                 }
  40.         }
  41. }
  42. /**
  43. * 消费者
  44. * @author Panda
  45. *
  46. */
  47. class Consumer implements Runnable{
  48.         Goods good = null;
  49.         public Consumer(Goods good){
  50.                 this.good = good;
  51.         }
  52.         @Override
  53.         public void run() {
  54.                 while(true){
  55.                         LockInstance.lockEg.lock();
  56.                         try {
  57.                                 while(!good.flag){
  58.                                         LockInstance.conCondtion.await();
  59.                                 }
  60.                                 good.show();
  61.                                 good.flag = false;
  62.                                 LockInstance.proCondtion.signal();
  63.                                 
  64.                         } catch (InterruptedException e) {
  65.                                 // TODO Auto-generated catch block
  66.                                 e.printStackTrace();
  67.                         }finally{
  68.                                 LockInstance.lockEg.unlock();
  69.                         }
  70.                 }
  71.         }
  72. }
  73. /**
  74. * 所有相关的锁的相关实例,为了方便操作,因而全部采用共有
  75. * @author Panda
  76. *
  77. */
  78. class LockInstance{
  79.         public  static Lock lockEg = new ReentrantLock();
  80.         public static Condition proCondtion = lockEg.newCondition();//生产者条件
  81.         public static Condition conCondtion = lockEg.newCondition();//消费者条件
  82. }

  83. class Goods{
  84.         int num = 0;
  85.         String name;
  86.         boolean flag = false;//为
  87.         /**
  88.          * 模拟生产商品
  89.          */
  90.         public void set(String name){
  91.         this.name=name;
  92.         num++;
  93.         System.out.println(Thread.currentThread().getName()+"生产第"+num+"件"+name);
  94.         }
  95.         
  96.         /**
  97.          * 模拟消费商品
  98.          */
  99.         public void show(){
  100.                 System.out.println(Thread.currentThread().getName()+"消费第"+num+"件"+name);
  101.         }
  102. }
复制代码


回复 使用道具 举报
楼上的总结好详细啊,复习啦、、、、
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马