加锁情况下生产者消费者的应用

来源:互联网 发布:京东域名买谁的 编辑:程序博客网 时间:2024/05/01 22:35

最近重新认识了锁,分享几篇文章

class Buffer{    final Lock lock=new ReentrantLock();//定义一个锁    final Condition notFull =lock.newCondition();//信号,没有满,可以塞入  条件等待    final Condition notEmtpy =lock.newCondition();//信号,表示没有空,可以取出        final  Object[] items=new Object[20];//模拟队列,大小10      int  putptr=0;//累计加 标记放入位置    int  takeptr=0;//累计加 标记取出位置    int count=0;//数组实时容量,放入+;取出-, 标记数组中元素被放入与被取出实时的个数 位置        public void push(Object  pushdata) throws InterruptedException    {        lock.lock();//锁定//        数组如果满了,不满阻塞        while(count==items.length)        {            System.out.println("线程"+Thread.currentThread().getId()+"被阻塞了,无法压入数据");            notFull.await();//没有满,可以塞入的 条件等待await        }//        没满放到数组中,判断是否满了 满了回到原点        items[putptr]=pushdata;//压入        if(++putptr==items.length)//下标++为数组的长度        {            putptr=0;//满了就回到原点。        }        ++count;//记录下元素数量        System.out.println("线程"+Thread.currentThread().getId()+"存好了数据"+pushdata);//存好了数据        notEmtpy.signal();//唤醒 通知过来取,表示没有空,可以取出  条件等待signal                lock.unlock();//解锁    }        public  void take() throws InterruptedException    {        lock.lock();//锁定        while(count==0)        {            System.out.println("线程"+Thread.currentThread().getId()+"被阻塞了,队列为空无法取来数据");            notEmtpy.await();//通知过来取,阻塞表示没有空,可以取出  条件等待signal        }                Object outdata=items[takeptr];        System.out.println("takeptr的值为:"+takeptr+"   items的长度为"+items.length);        if(++takeptr==items.length)//takeptr在此处自增 从0 1 2...19 items的带大小固定为:20          {            takeptr=0;//当为16了让takeptr重新从0开始再次计算        }         --count;//记录下uuansu数量                System.out.println("线程"+Thread.currentThread().getId()+"去除了数据"+outdata);//存好了数据         notFull.signal();        lock.unlock();//解锁        //        return outdata;    }}public class ProducerAndConsumer {    public static void main(String[] args)    {             Buffer bf=new  Buffer();//创建缓存                  for(int i=0;i<24;i++)         {             new Thread( (Runnable) ()->{                try                  {                     bf.push(new Random().nextInt(1000));                 } catch (InterruptedException ex) {                     Logger.getLogger(ProducerAndConsumer.class.getName()).log(Level.SEVERE, null, ex);                 }             }  ).start();         }                 for(int i=0;i<24;i++)         {             new Thread( (Runnable) ()->{                 try                  {//                 Integer data= (Integer)                     bf.take();                 } catch (InterruptedException ex) {                     Logger.getLogger(ProducerAndConsumer.class.getName()).log(Level.SEVERE, null, ex);                 }             } ).start();         }             }}
push压入数组的处理:

  将数据放入数组  主要是对await阻塞的处理
  思路:操作前后加锁。数组容量count如果满了,notFull 不满await阻塞  对数据进行压入数组处理,notEmtpy不空 signal唤醒
  压入数组时,  数组如果数组容量count满了,打印数组满阻塞并让notFull 不满条件等待 await阻塞;如果没有满,把数据放入数组putptr位置,
  位置下标putptr++并如果为数组长度则将putptr置0,否则记录实时数组中元素个数count++,打印存入数据,notEmtpy不空 条件等待signal唤醒,解锁

take从数组中取出的处理

    将数据从数组中拿出来Object
    思路:操作前后加锁,数组容量count如果为空,notEmtpy 不空await阻塞  对数据进行取出数据处理,notFull满 signal唤醒
    从数组中取时,如果数组容量count为0,打印数组空并让notEmpty 不空条件等待await阻塞,如果没有空,取出数组takeptr位置的值,
    位置下标takeptr++并如果为数组长度则将takeptr置0,否则记录实时数组中元素个数count--,打印取出数据, notFull不满signal()唤醒,解锁。



0 0
原创粉丝点击