要求:使用两个线程交叉打印 n 次 ”foo” 和 ”bar”
1.FooBar 类
定义 foo 和 bar 的方法用来控制如何打印字符串。
foo 和 bar 方法接受一个 runnable 类,prinFoo, 和 printBar 为参数 该类用于在控制台输出一个字符串 ”foo” 或者 ”bar”。foo 和 bar 方法判断是否满足打印条件,并且执行 n 次。如果不满足条件,则暂时阻塞。
package ThreadLeetcode;
class FooBar {
private int n;
private volatile boolean finish=false;
public FooBar(int n) {this.n = n;}
public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {// printFoo.run() outputs "foo". Do not change or remove this line.
while(finish){Thread.yield();
}
printFoo.run();
finish=true;
}
}
public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {// printBar.run() outputs "bar". Do not change or remove this line.
while (!finish){Thread.yield();
}
printBar.run();
finish=false;
}
}
}
2.printBar 和 printFoo 类
定义一个 Runnable 类用于启动线程,打印字符串
package ThreadLeetcode;
public class PrintBar implements Runnable{
@Override
public void run() {System.out.printf("Bar\n");
}
}
package ThreadLeetcode;
public class PrintFoo implements Runnable{
@Override
public void run() {System.out.printf("Foo\n");
}
}
3.fooBarTest 类
用于测试
package ThreadLeetcode;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class FooBarTest {
private ThreadPoolExecutor executor;
public static void main(String[] args) throws InterruptedException{
// Init executor
ThreadPoolExecutor executor;
executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(2);
// init Task
FooBar fooBar = new FooBar(4);
FooTast fooTast = new FooTast(fooBar);
BarTast barTast = new BarTast(fooBar);
// Submit Task
executor.submit(fooTast);
executor.submit(barTast);
// End Task
while (executor.getActiveCount()>0){Thread.sleep(50);
}
executor.shutdown();}
}
class FooTast implements Runnable {PrintFoo printFoo = new PrintFoo();
FooBar fooBar;
public FooTast(FooBar foobar) {this.fooBar = foobar;}
@Override
public void run() {
try {fooBar.foo(printFoo);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
class BarTast implements Runnable {PrintBar printBar = new PrintBar();
FooBar fooBar;
public BarTast(FooBar foobar) {this.fooBar = foobar;}
@Override
public void run() {
try {fooBar.bar(printBar);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
备注:
Thread 类中 run() 和 start() 方法的区别如下:
run() 方法: 在本线程内调用该 Runnable 对象的 run() 方法,可以重复多次调用;
start() 方法: 启动一个线程,调用该 Runnable 对象的 run() 方法,不能多次启动一个线程