一道典型的 一个生产者、一个消费者的场景
wait + notify
class FooBar {
private int n;
boolean available = false;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (this) {
if (available) {
this.wait();
}
printFoo.run();
this.notify();
this.available = !this.available;
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (this) {
if (!available) {
this.wait();
}
printBar.run();
this.notify();
this.available = !this.available;
}
}
}
}
BlockingQueue
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
class FooBar {
private int n;
BlockingQueue<Integer> q1 = new LinkedBlockingQueue<>();
BlockingQueue<Integer> q2 = new LinkedBlockingQueue<>();
public FooBar(int n) {
this.n = n;
q1.offer(0);
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
q1.take();
printFoo.run();
q2.put(0);
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
q2.take();
printBar.run();
q1.put(0);
}
}
}
SynchronousQueue
顺序要注意一下。
class FooBar {
private SynchronousQueue<Integer> queue1 = new SynchronousQueue<>(), queue2 = new SynchronousQueue<>();
private int n;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
printFoo.run();
queue2.put(0);
queue1.take();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
queue2.take();
printBar.run();
queue1.put(0);
}
}
}
此题使用 信号量似乎也是很合适的。