001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.modeshape.common.collection.ring; 018 019import java.util.concurrent.locks.Condition; 020import java.util.concurrent.locks.Lock; 021import java.util.concurrent.locks.ReentrantLock; 022 023/** 024 * A {@link WaitStrategy} that blocks the current thread until an entry is available for consumption. This implementation uses 025 * Java locks and {@link Condition conditions}. 026 * 027 * @author Randall Hauch (rhauch@redhat.com) 028 */ 029public class BlockingWaitStrategy implements WaitStrategy { 030 031 private final Lock lock = new ReentrantLock(); 032 private final Condition waitCondition = lock.newCondition(); 033 034 @Override 035 public long waitFor( long position, 036 Pointer pointer, 037 Pointer dependentPointer, 038 PointerBarrier barrier ) throws InterruptedException { 039 // Get the next position that is immediately available ... 040 long availablePosition = pointer.get(); 041 if (availablePosition < position) { 042 // The caller wants a position that is farther along than what is available, so we have to block ... 043 lock.lock(); 044 try { 045 while (!barrier.isComplete() && (availablePosition = pointer.get()) < position) { 046 waitCondition.await(); 047 } 048 } finally { 049 lock.unlock(); 050 } 051 } 052 return availablePosition; 053 } 054 055 @Override 056 public void signalAllWhenBlocking() { 057 lock.lock(); 058 try { 059 waitCondition.signalAll(); 060 } finally { 061 lock.unlock(); 062 } 063 } 064}