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