1 题目

交替打印 FooBar

2 解

2.1 我的解

思路,先打印 Foo,然后通知另一个线程打印 Bar

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class FooBar {
    private int n;

    public FooBar(int n) {
        this.n = n;
    }
    
    private boolean isPrintFoo = false;

    public synchronized void foo(Runnable printFoo) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
        	// printFoo.run() outputs "foo". Do not change or remove this line.
        	printFoo.run();
            isPrintFoo = true;
            this.notify();
            this.wait();
        }
    }

    public synchronized void bar(Runnable printBar) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
            if (!isPrintFoo) {
                this.wait();
            }
            // printBar.run() outputs "bar". Do not change or remove this line.
        	printBar.run();
            isPrintFoo = false;
            this.notify();
        }
    }
}

2.2 别人的解

用信号量来实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.concurrent.Semaphore;

/*
semaphore 与 semaphore2 在下面四种状态转换

semaphore semaphore2 代码位置
1         0          准备打印 Foo
0         0          打印 Foo
0         1          准备打印 Bar
0         0          打印 Bar
*/

class FooBar {
    private int n;
    private Semaphore semaphore = new Semaphore(1);
    private Semaphore semaphore2 = new Semaphore(0);
    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
            semaphore.acquire();
        	// printFoo.run() outputs "foo". Do not change or remove this line.
        	printFoo.run();
        	semaphore2.release();
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        
        for (int i = 0; i < n; i++) {
            semaphore2.acquire();
            // printBar.run() outputs "bar". Do not change or remove this line.
        	printBar.run();
            semaphore.release();
        }
    }
}