1115、交替打印FooBar
给定一个类
class FooBar {
public void foo() {
for (int i = 0; i < n; i++) {
print("foo");
}
}
public void bar() {
for (int i = 0; i < n; i++) {
print("bar");
}
}
}
两个不同的线程将会共用一个 FooBar 实例:
线程 A 将会调用 foo() 方法,而
线程 B 将会调用 bar() 方法
请设计修改程序,以确保 "foobar" 被输出 n 次。
解法1、volatile+Thread.yield()运行状态变为就绪状态
class FooBar {
private int n;
public FooBar(int n) {
this.n = n;
}
private volatile boolean wall=true;
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n;) {
if(wall){
printFoo.run();//打印foo
i++;
wall=false;//设置wall,在打印bar之前不会再进入,打印foo
}else{
Thread.yield();//这个线程再次执行到这里,执行态进入就绪态
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n;) {
if(!wall){
printBar.run();//打印bar
i++;
wall=true;
}else{
Thread.yield();
}
}
}
}
解法二:synchronized+锁标记+唤醒
class FooBar {
private int n;
public FooBar(int n) {
this.n = n;
}
private volatile boolean wall=true;
private final Object foo=new Object();//锁标志
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n;i++ ) {
synchronized(foo){//线程获取资源foo并上锁
while(!wall){
foo.wait();//如果wall为false,当前线程退让同步资源锁。
}
printFoo.run();
wall=false;
foo.notifyAll();//资源唤醒
}
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n;i++) {
synchronized(foo){
while(wall){
foo.wait();
}
printBar.run();
wall=true;
foo.notifyAll();
}
}
}
}