semaphore
import java.util.concurrent.Semaphore;
class FooBar {
private int n;
Semaphore foo = new Semaphore(1);
Semaphore bar = new Semaphore(0);
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
foo.acquire();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
bar.release();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
bar.acquire();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
foo.release();
}
}
}
synchronzed
class FooBar {
private int n;
private Object obj = new Object();
boolean foo = true;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (obj) {
while (!foo) {
obj.wait();
}
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
foo = false;
obj.notifyAll();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
synchronized (obj) {
while (foo) {
obj.wait();
}
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
foo = true;
obj.notifyAll();
}
}
}
}
ReentrantLock
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class FooBar {
private int n;
ReentrantLock lock = new ReentrantLock();
Condition foo = lock.newCondition();
Condition bar = lock.newCondition();
boolean f = true;
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
while (!f) {
foo.await();
}
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
f = false;
bar.signalAll();
} finally {
lock.unlock();
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
while (f) {
bar.await();
}
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
f = true;
foo.signalAll();
} finally {
lock.unlock();
}
}
}
}
BlockingQueue
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class FooBar {
private int n;
BlockingQueue q1 = new LinkedBlockingQueue();
BlockingQueue q2 = new LinkedBlockingQueue();
public FooBar(int n) {
this.n = n;
q1.add(1);
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
q1.take();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
q2.add(1);
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
q2.take();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
q1.add(1);
}
}
}