黑马程序员技术交流社区
标题:
关于多线程结合Lock锁对象实现数组中随机存取动作的过程
[打印本页]
作者:
quan23355
时间:
2013-11-27 21:06
标题:
关于多线程结合Lock锁对象实现数组中随机存取动作的过程
本帖最后由 quan23355 于 2013-11-28 12:28 编辑
这是比老师的视频中第14天多线程31节中的例子,我模拟了其过程,有哪位大牛能详细解释下BoundedBuffer类中随机存取的过程么?我想理清下思路
class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();
final Object[] items = new Object[100];
int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
class Run implements Runnable{
BoundedBuffer bb=null;
boolean b=false;
int x=0;
Run(BoundedBuffer bb,boolean b){
this.bb=bb;
this.b=b;
}
public void run() {
while(x!=100){
if(b){
try {
bb.put(++x+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
System.out.println(bb.take().toString());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class test{
public static void main(String[] args){
BoundedBuffer bb=new BoundedBuffer();
Run r=new Run(bb, true);
Run r1=new Run(bb, false);
Thread t1=new Thread(r);
Thread t2=new Thread(r1);
t1.start();
t2.start();
}
}
复制代码
作者:
ysunday
时间:
2013-11-27 21:59
notEmpty表示的是缓存非空,那么notEmpty.await()表示的意识就是缓存非空这个条件为假(同意是‘现在缓存是空的!’所以,老大给我停下来),相应的notEmpty.signal() 就表示缓存非空为真,然后就祈祷:神啊!(在这里的神当然指的是系统调度了)我已经准备好了,可以开始了。同理也能够理解notFull了。
至于原理,把代码看懂就知道原理了估计。好好看吧少年
作者:
ysunday
时间:
2013-11-27 22:07
/*
File: BoundedBuffer.java
Originally written by Doug Lea and released into the public domain.
This may be used for any purposes whatsoever without acknowledgment.
Thanks for the assistance and support of Sun Microsystems Labs,
and everyone contributing, testing, and using this code.
History:
Date Who What
11Jun1998 dl Create public version
17Jul1998 dl Simplified by eliminating wait counts
25aug1998 dl added peek
5May1999 dl replace % with conditional (slightly faster)
*/
package EDU.oswego.cs.dl.util.concurrent;
/**
* Efficient array-based bounded buffer class.
* Adapted from CPJ, chapter 8, which describes design.
* <p>[<a > Introduction to this package. </a>] <p>
**/
public class BoundedBuffer implements BoundedChannel {
protected final Object[] array_; // the elements
protected int takePtr_ = 0; // circular indices
protected int putPtr_ = 0;
protected int usedSlots_ = 0; // length
protected int emptySlots_; // capacity - length
/**
* Helper monitor to handle puts.
**/
protected final Object putMonitor_ = new Object();
/**
* Create a BoundedBuffer with the given capacity.
* @exception IllegalArgumentException if capacity less or equal to zero
**/
public BoundedBuffer(int capacity) throws IllegalArgumentException {
if (capacity <= 0) throw new IllegalArgumentException();
array_ = new Object[capacity];
emptySlots_ = capacity;
}
/**
* Create a buffer with the current default capacity
**/
public BoundedBuffer() {
this(DefaultChannelCapacity.get());
}
/**
* Return the number of elements in the buffer.
* This is only a snapshot value, that may change
* immediately after returning.
**/
public synchronized int size() { return usedSlots_; }
public int capacity() { return array_.length; }
protected void incEmptySlots() {
synchronized(putMonitor_) {
++emptySlots_;
putMonitor_.notify();
}
}
protected synchronized void incUsedSlots() {
++usedSlots_;
notify();
}
protected final void insert(Object x) { // mechanics of put
--emptySlots_;
array_[putPtr_] = x;
if (++putPtr_ >= array_.length) putPtr_ = 0;
}
protected final Object extract() { // mechanics of take
--usedSlots_;
Object old = array_[takePtr_];
array_[takePtr_] = null;
if (++takePtr_ >= array_.length) takePtr_ = 0;
return old;
}
public Object peek() {
synchronized(this) {
if (usedSlots_ > 0)
return array_[takePtr_];
else
return null;
}
}
public void put(Object x) throws InterruptedException {
if (x == null) throw new IllegalArgumentException();
if (Thread.interrupted()) throw new InterruptedException();
synchronized(putMonitor_) {
while (emptySlots_ <= 0) {
try { putMonitor_.wait(); }
catch (InterruptedException ex) {
putMonitor_.notify();
throw ex;
}
}
insert(x);
}
incUsedSlots();
}
public boolean offer(Object x, long msecs) throws InterruptedException {
if (x == null) throw new IllegalArgumentException();
if (Thread.interrupted()) throw new InterruptedException();
synchronized(putMonitor_) {
long start = (msecs <= 0)? 0 : System.currentTimeMillis();
long waitTime = msecs;
while (emptySlots_ <= 0) {
if (waitTime <= 0) return false;
try { putMonitor_.wait(waitTime); }
catch (InterruptedException ex) {
putMonitor_.notify();
throw ex;
}
waitTime = msecs - (System.currentTimeMillis() - start);
}
insert(x);
}
incUsedSlots();
return true;
}
public Object take() throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Object old = null;
synchronized(this) {
while (usedSlots_ <= 0) {
try { wait(); }
catch (InterruptedException ex) {
notify();
throw ex;
}
}
old = extract();
}
incEmptySlots();
return old;
}
public Object poll(long msecs) throws InterruptedException {
if (Thread.interrupted()) throw new InterruptedException();
Object old = null;
synchronized(this) {
long start = (msecs <= 0)? 0 : System.currentTimeMillis();
long waitTime = msecs;
while (usedSlots_ <= 0) {
if (waitTime <= 0) return null;
try { wait(waitTime); }
catch (InterruptedException ex) {
notify();
throw ex;
}
waitTime = msecs - (System.currentTimeMillis() - start);
}
old = extract();
}
incEmptySlots();
return old;
}
}
复制代码
要是愿意研究,源码我给你贴出来了
再给你个网址,太多了,实在读不下去了
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2