Locks
The java.util.concurrent.locks package provides interfaces and classes for locking and waiting.
This Lock interface provides more locking operations than the synchronized keyword. Lock supports a wait/notification mechanism through associated Condition objects.
Lock objects can back out of an attempt to acquire a lock. The tryLock() method backs out when the lock is not available immediately or when a timeout expires.
The lockInterruptibly() method backs out when another thread sends an interrupt before the lock is acquired.
ReentrantLock implements Lock, describing a reentrant mutual exclusion Lock implementation.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
final BlockingQueue<Character> bq;
bq = new ArrayBlockingQueue<Character>(26);
final ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable producer;
producer = new Runnable() {
public void run() {
for (char ch = 'A'; ch <= 'F'; ch++) {
try {
lock.lock();
try {
while (!bq.offer(ch)) {
lock.unlock();
Thread.sleep(1000);
lock.lock();
}
System.out.println(ch + " produced by producer.");
} catch (InterruptedException ie) {
assert false;
}
} finally {
lock.unlock();
}
}
}
};
executor.execute(producer);
Runnable consumer;
consumer = new Runnable() {
public void run() {
char ch = '\0';
do {
try {
lock.lock();
try {
Character c;
while ((c = bq.poll()) == null) {
lock.unlock();
Thread.sleep(1000);
lock.lock();
}
ch = c;
System.out.println(ch + " consumed by consumer.");
} catch (InterruptedException ie) {
assert false;
}
} finally {
lock.unlock();
}
} while (ch != 'F');
executor.shutdownNow();
}
};
executor.execute(consumer);
}
}