1. 条件队列
@ThreadSafe
public abstract class BaseBoundedBuffer<V>{
@GuardedBy("this") private final V[] buf;
@GuardedBy("this") private final int tail;
@GuardedBy("this") private final int head;
@GuardedBy("this") private final int count;
protected BaseBoundedBuffer(int capacity){
this.buf = (V[])new Object[];
}
protected synchronized final void doPut(V v){
buf[tail] = v;
if(++tail == buf.length){
tail =0;
}
++count;
}
protected synchronized final V doTake(){
V v = buf[head];
buf[head] = null;
if(++head == buf.length){
head = 0;
}
--count;
return v;
}
protected synchronized final boolean isFull(){
return count == buf.length;
}
protected synchronized final boolean isEmpty(){
return count == 0;
}
}
1. 轮询
使用者在使用上面的类时,循环调用响应的方法,直到成功。
缺点:CPU消耗比较高
2. 休眠
@ThreadSafe
public class GrumpyBoundedBuffer<V> extends BaseBoundedBuffer<V>{
public GrumpyBoundedBuffer(int size){
super(size);
}
public synchronized void put(V v) throws BufferFullException{
while(true){
synchronized(this){
if(!isFull()){
doPut(v);
return ;
}
}
Thread.sleep(SLEEP_GRANULARITY);
}
}
public synchronized void take(V v) throws BufferEmptyException{
while(true){
synchronized(this){
if(!isEmpty()){
return doTake(v);;
}
}
Thread.sleep(SLEEP_GRANULARITY);
}
}
}
缺点:响应时间差,有延迟。
3. 条件队列
每个对象都可以作为一个条件队列,就像每个对象都可以作为一个锁。
对象的wait、notify、notifyAll方法构成了内部条件队列的API,对象的内置锁与内部条件队列是相互关联的,要调用对象中的条件队列的任何一个方法,必须持有对象上的锁。
@ThreadSafe
public class BoundedBuffer<V> extends BaseBoundedBuffer<V>{
public BoundedBuffer(int size){
super(size);
}
public synchronized void put(V v) throws BufferFullException{
while(isFull()){
wait();
}
doPut(v);
notifyAll();
}
public synchronized void take(V v) throws BufferEmptyException{
while(isEmpty()){
wait();
}
V v = doTake(v);
notifyAll();
return v;
}
}
优点:CPU效率、上下文切换开销、响应性 都有了一定的优化。
2. 使用条件队列构建同步工具
使用条件队列的关键是找出条件谓词。另外所对象和条件队列对象必须是一个对象。下面是条件等待的标准形式:
void stateDependentMethod() throws InterruptedException{
synchronized(lock){
while(!conditionPredication){
lock.wait();
}
}
}
123