class ZeroEvenOdd {
private int n;
private static Semaphore z = new Semaphore(1);
private static Semaphore e = new Semaphore(0);
private static Semaphore o = new Semaphore(0);
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
for (int i=1; i<=n; i++){
z.acquire();
printNumber.accept(0);
if ((i&1)==0){
e.release();
} else {
o.release();
}
}
}
/**
* 输出偶数
*/
public void even(IntConsumer printNumber) throws InterruptedException {
for (int i=2; i<=n; i+=2){
e.acquire();
printNumber.accept(i);
z.release();
}
}
/**
* 输出奇数
*/
public void odd(IntConsumer printNumber) throws InterruptedException {
for (int i=1; i<=n; i+=2){
o.acquire();
printNumber.accept(i);
z.release();
}
}
}
解题2:synchronized独占锁+线程阻塞与唤醒
class ZeroEvenOdd {
private int n;
private boolean first;
private boolean second;
private boolean zoo = true;
public ZeroEvenOdd(int n) {
this.n = n;
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero(IntConsumer printNumber) throws InterruptedException {
synchronized(this){
for(int i=1;i<=n;i++){
while(!zoo){
this.wait();
}
printNumber.accept(0);
zoo = false;
if(i%2!=0){
first = true;
}else{
second = true;
}
this.notifyAll();
}
}
}
public void even(IntConsumer printNumber) throws InterruptedException {
synchronized(this){
for(int i=2;i<=n;i+=2){
while(!second){
this.wait();
}
printNumber.accept(i);
second = false;
zoo = true;
this.notifyAll();
}
}
}
public void odd(IntConsumer printNumber) throws InterruptedException {
synchronized(this){
for(int i=1;i<=n;i+=2){
while(!first){
this.wait();
}
printNumber.accept(i);
first = false;
zoo = true;
this.notifyAll();
}
}
}
}
拓展
信号量的初始值有何讲究?0?1?-1?
If the value is positive, then it represents the number of threads that can decrement without blocking. If it is negative, then it represents the number of threads that have blocked and are waiting. If the value is zero, it means there are no threads waiting, but if a thread tries to decrement, it will block.