Both methods are to be called by multiple threads. Each thread calling either method becomes blocking and when one thread finds that there are already at least two threads calling H() and at least one thread calling O(), let two threads calling H() and one thread calling O() resume from blocking in order to produce a water molecular.
A solution using java.util.concurrent.locks.ReentrantLock
.
-
import java.util.concurrent.locks.Condition;
-
import java.util.concurrent.locks.Lock;
-
import java.util.concurrent.locks.ReentrantLock;
-
-
public class H2O {
-
-
static final int H = 0;
-
static final int O = 1;
-
static final Lock LOCK = new ReentrantLock();
-
static final Condition ENOUGH[] = {LOCK.newCondition(), LOCK.newCondition()};
-
static final int NEEDED[] = {2, 1};
-
static final int COUNT[] = {0, 0};
-
-
static void run(int index) {
-
LOCK.lock();
-
try {
-
if(COUNT[H] >= NEEDED[H] && COUNT[O] >= NEEDED[O]) {
-
for(int i = 0, n = NEEDED[H]; i < n; ++i) {
-
ENOUGH[H].signal();
-
}
-
COUNT[H] -= NEEDED[H];
-
for(int i = 0, n = NEEDED[O]; i < n; ++i) {
-
ENOUGH[O].signal();
-
}
-
COUNT[O] -= NEEDED[O];
-
}
-
++COUNT[index];
-
ENOUGH[index].awaitUninterruptibly();
-
} finally {
-
LOCK.unlock();
-
}
-
}
-
-
public static void h() {
-
run(H);
-
}
-
-
public static void o() {
-
run(O);
-
}
-
}
Post new comment