Java多线程练习交叉打印字符串

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理