2019年11月22日
目录
题目:1116. 打印零与奇偶数
解题1:Semaphore 信号量作屏障
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.
如果该值为正,则表示可以在不阻塞的情况下减少的线程数。
如果为负,则表示已阻塞且正在等待的线程数。
如果该值为零,则表示没有线程在等待,但如果线程尝试递减,则它将阻塞。
- IntConsumer 是什么编程手法?
Consumer是java8提供的函数式接口之一,意思为消费者,接受参数而不返回值。
Consumer还有多个其他的接口,具体有以下几种,在使用函数式接口时,若有提供具体类型的接口,就尽量使用此接口,因为具体的类型指定可以避免装箱拆箱时所带来的额外资源消耗
参考:https://zhuanlan.zhihu.com/p/81626432