黑马程序员技术交流社区

标题: 关于多线程结合Lock锁对象实现数组中随机存取动作的过程 [打印本页]

作者: quan23355    时间: 2013-11-27 21:06
标题: 关于多线程结合Lock锁对象实现数组中随机存取动作的过程
本帖最后由 quan23355 于 2013-11-28 12:28 编辑

这是比老师的视频中第14天多线程31节中的例子,我模拟了其过程,有哪位大牛能详细解释下BoundedBuffer类中随机存取的过程么?我想理清下思路
  1. class BoundedBuffer {
  2.            final Lock lock = new ReentrantLock();
  3.            final Condition notFull  = lock.newCondition();
  4.            final Condition notEmpty = lock.newCondition();

  5.            final Object[] items = new Object[100];
  6.            int putptr, takeptr, count;

  7.            public void put(Object x) throws InterruptedException {
  8.              lock.lock();
  9.              try {
  10.                while (count == items.length)
  11.                  notFull.await();
  12.                items[putptr] = x;
  13.                if (++putptr == items.length) putptr = 0;
  14.                ++count;
  15.                notEmpty.signal();
  16.              } finally {
  17.                lock.unlock();
  18.              }
  19.            }

  20.            public Object take() throws InterruptedException {
  21.              lock.lock();
  22.              try {
  23.                while (count == 0)
  24.                  notEmpty.await();
  25.                Object x = items[takeptr];
  26.                if (++takeptr == items.length) takeptr = 0;
  27.                --count;
  28.                notFull.signal();
  29.                return x;
  30.              } finally {
  31.                lock.unlock();
  32.              }
  33.            }
  34.          }

  35. class Run implements Runnable{
  36.         
  37.         BoundedBuffer bb=null;
  38.         boolean  b=false;
  39.         int x=0;
  40.         Run(BoundedBuffer bb,boolean b){
  41.                 this.bb=bb;
  42.                 this.b=b;
  43.         }
  44.         public void run() {
  45.                 while(x!=100){
  46.                         if(b){
  47.                                 try {
  48.                                         bb.put(++x+"");
  49.                                 } catch (InterruptedException e) {
  50.                                         e.printStackTrace();
  51.                                 }
  52.                         }else{
  53.                                 try {
  54.                                         System.out.println(bb.take().toString());
  55.                                 } catch (InterruptedException e) {
  56.                                         e.printStackTrace();
  57.                                 }
  58.                         }
  59.                 }
  60.         }
  61.         
  62. }

  63. public class test{
  64.         public static void main(String[] args){
  65.                 BoundedBuffer bb=new BoundedBuffer();
  66.                 Run r=new Run(bb, true);
  67.                 Run r1=new Run(bb, false);
  68.                 Thread t1=new Thread(r);
  69.                 Thread t2=new Thread(r1);
  70.                 t1.start();
  71.                 t2.start();
  72.         }
  73. }
复制代码




作者: ysunday    时间: 2013-11-27 21:59
notEmpty表示的是缓存非空,那么notEmpty.await()表示的意识就是缓存非空这个条件为假(同意是‘现在缓存是空的!’所以,老大给我停下来),相应的notEmpty.signal() 就表示缓存非空为真,然后就祈祷:神啊!(在这里的神当然指的是系统调度了)我已经准备好了,可以开始了。同理也能够理解notFull了。

至于原理,把代码看懂就知道原理了估计。好好看吧少年
作者: ysunday    时间: 2013-11-27 22:07
  1. /*
  2.   File: BoundedBuffer.java

  3.   Originally written by Doug Lea and released into the public domain.
  4.   This may be used for any purposes whatsoever without acknowledgment.
  5.   Thanks for the assistance and support of Sun Microsystems Labs,
  6.   and everyone contributing, testing, and using this code.

  7.   History:
  8.   Date       Who                What
  9.   11Jun1998  dl               Create public version
  10.   17Jul1998  dl               Simplified by eliminating wait counts
  11.   25aug1998  dl               added peek
  12.    5May1999  dl               replace % with conditional (slightly faster)
  13. */

  14. package EDU.oswego.cs.dl.util.concurrent;

  15. /**
  16. * Efficient array-based bounded buffer class.
  17. * Adapted from CPJ, chapter 8, which describes design.
  18. * <p>[<a > Introduction to this package. </a>] <p>
  19. **/

  20. public class BoundedBuffer implements BoundedChannel {

  21.   protected final Object[]  array_;      // the elements

  22.   protected int takePtr_ = 0;            // circular indices
  23.   protected int putPtr_ = 0;      

  24.   protected int usedSlots_ = 0;          // length
  25.   protected int emptySlots_;             // capacity - length

  26.   /**
  27.    * Helper monitor to handle puts.
  28.    **/
  29.   protected final Object putMonitor_ = new Object();

  30.   /**
  31.    * Create a BoundedBuffer with the given capacity.
  32.    * @exception IllegalArgumentException if capacity less or equal to zero
  33.    **/
  34.   public BoundedBuffer(int capacity) throws IllegalArgumentException {
  35.     if (capacity <= 0) throw new IllegalArgumentException();
  36.     array_ = new Object[capacity];
  37.     emptySlots_ = capacity;
  38.   }

  39.   /**
  40.    * Create a buffer with the current default capacity
  41.    **/

  42.   public BoundedBuffer() {
  43.     this(DefaultChannelCapacity.get());
  44.   }

  45.   /**
  46.    * Return the number of elements in the buffer.
  47.    * This is only a snapshot value, that may change
  48.    * immediately after returning.
  49.    **/
  50.   public synchronized int size() { return usedSlots_; }

  51.   public int capacity() { return array_.length; }

  52.   protected void incEmptySlots() {
  53.     synchronized(putMonitor_) {
  54.       ++emptySlots_;
  55.       putMonitor_.notify();
  56.     }
  57.   }

  58.   protected synchronized void incUsedSlots() {
  59.     ++usedSlots_;
  60.     notify();
  61.   }

  62.   protected final void insert(Object x) { // mechanics of put
  63.     --emptySlots_;
  64.     array_[putPtr_] = x;
  65.     if (++putPtr_ >= array_.length) putPtr_ = 0;
  66.   }

  67.   protected final Object extract() { // mechanics of take
  68.     --usedSlots_;
  69.     Object old = array_[takePtr_];
  70.     array_[takePtr_] = null;
  71.     if (++takePtr_ >= array_.length) takePtr_ = 0;
  72.     return old;
  73.   }

  74.   public Object peek() {
  75.     synchronized(this) {
  76.       if (usedSlots_ > 0)
  77.         return array_[takePtr_];
  78.       else
  79.         return null;
  80.     }
  81.   }


  82.   public void put(Object x) throws InterruptedException {
  83.     if (x == null) throw new IllegalArgumentException();
  84.     if (Thread.interrupted()) throw new InterruptedException();

  85.     synchronized(putMonitor_) {
  86.       while (emptySlots_ <= 0) {
  87.         try { putMonitor_.wait(); }
  88.         catch (InterruptedException ex) {
  89.           putMonitor_.notify();
  90.           throw ex;
  91.         }
  92.       }
  93.       insert(x);
  94.     }
  95.     incUsedSlots();
  96.   }

  97.   public boolean offer(Object x, long msecs) throws InterruptedException {
  98.     if (x == null) throw new IllegalArgumentException();
  99.     if (Thread.interrupted()) throw new InterruptedException();

  100.     synchronized(putMonitor_) {
  101.       long start = (msecs <= 0)? 0 : System.currentTimeMillis();
  102.       long waitTime = msecs;
  103.       while (emptySlots_ <= 0) {
  104.         if (waitTime <= 0) return false;
  105.         try { putMonitor_.wait(waitTime); }
  106.         catch (InterruptedException ex) {
  107.           putMonitor_.notify();
  108.           throw ex;
  109.         }
  110.         waitTime = msecs - (System.currentTimeMillis() - start);
  111.       }
  112.       insert(x);
  113.     }
  114.     incUsedSlots();
  115.     return true;
  116.   }



  117.   public  Object take() throws InterruptedException {
  118.     if (Thread.interrupted()) throw new InterruptedException();
  119.     Object old = null;
  120.     synchronized(this) {
  121.       while (usedSlots_ <= 0) {
  122.         try { wait(); }
  123.         catch (InterruptedException ex) {
  124.           notify();
  125.           throw ex;
  126.         }
  127.       }
  128.       old = extract();
  129.     }
  130.     incEmptySlots();
  131.     return old;
  132.   }

  133.   public  Object poll(long msecs) throws InterruptedException {
  134.     if (Thread.interrupted()) throw new InterruptedException();
  135.     Object old = null;
  136.     synchronized(this) {
  137.       long start = (msecs <= 0)? 0 : System.currentTimeMillis();
  138.       long waitTime = msecs;
  139.       
  140.       while (usedSlots_ <= 0) {
  141.         if (waitTime <= 0) return null;
  142.         try { wait(waitTime); }
  143.         catch (InterruptedException ex) {
  144.           notify();
  145.           throw ex;
  146.         }
  147.         waitTime = msecs - (System.currentTimeMillis() - start);

  148.       }
  149.       old = extract();
  150.     }
  151.     incEmptySlots();
  152.     return old;
  153.   }

  154. }
复制代码


要是愿意研究,源码我给你贴出来了
再给你个网址,太多了,实在读不下去了
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2