要求:使用两个线程交叉打印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()方法,不能多次启动一个线程