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实现的信号量。




























