读书人

Java多线程开发6锁、条件变量、信

发布时间: 2012-12-23 11:28:15 作者: rapoo

Java多线程开发六——锁、条件变量、信号量 收藏
原创 Java多线程开发六——锁、条件变量、信号量 收藏

1.锁和条件变量
JDK1.5以上提供了锁和条件变量来控制线程的同步,想必同步方法和等待/通知函数,锁和条件变量提供了更直观的使用形式,更广泛的锁定操作,更灵活的数据结构。此外,多个条件变量可以和一个锁绑定。
使用示例,代码来源于JDK文档,可以看一下基本的用法。

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();

}

}

}


锁代替了synchronized的使用,Condition代替了对象监控器方法(wait,notify)的使用。

2.信号量
信号量经常用来限制访问有限资源的线程数量。见一个例子(来源于JDK文档):


class Pool {

private static final MAX_AVAILABLE = 100;

private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);



public Object getItem() throws InterruptedException {

available.acquire();//获取许可

return getNextAvailableItem();

}



public void putItem(Object x) {

if (markAsUnused(x))

available.release();//释放许可

}



// Not a particularly efficient data structure; just for demo



protected Object[] items = ... whatever kinds of items being managed

protected boolean[] used = new boolean[MAX_AVAILABLE];



protected synchronized Object getNextAvailableItem() {

for (int i = 0; i < MAX_AVAILABLE; ++i) {

if (!used[i]) {

used[i] = true;

return items[i];

}

}

return null; // not reached

}



protected synchronized boolean markAsUnused(Object item) {

for (int i = 0; i < MAX_AVAILABLE; ++i) {

if (item == items[i]) {

if (used[i]) {

used[i] = false;

return true;

} else

return false;

}

}

return false;

}



}

例子中最大支持100个线程并发访问,当前100个线程没有释放许可时,第101个线程就只能等待。
以上是简单的使用说明,如果需要了解更详细的信息,参考JDK文档。

附:一个用synchronized和wait、notify实现的信号量。

public class Semaphore {
private int count;
public Semaphore(int count){
this.count=count;
}
synchronized public void acquire() {//throws InterruptedException{
while (count==0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
count --;
}
synchronized public void release(){
count ++;
notify();
}
}

读书人网 >编程

热点推荐