交替打印foo和bar

题目

class FooBar {
    private int n;

    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.
            printFoo.run();
        }
    }

    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.
            printBar.run();
        }
    }
}

两个线程分别执行foo方法和bar方法,实现n次打印foobar,调用线程大概是这样的

调用线程

public class Main {
    public static void main(String[] args) {
        FooBar fooBar = new FooBar(5);

        Runnable printFoo = () -> System.out.print("foo");
        Runnable printBar = () -> System.out.print("bar\n");

        Thread t1 = new Thread(() -> {
            try {
                fooBar.foo(printFoo);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                fooBar.bar(printBar);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        t1.start();
        t2.start();
    }
}

Semaphore实现

import java.util.concurrent.Semaphore;

class FooBar {
    private int n;
    private final Semaphore fooSem = new Semaphore(1);  // 先允许 foo 执行
    private final Semaphore barSem = new Semaphore(0);  // bar 一开始不能执行

    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            fooSem.acquire();
            printFoo.run();
            barSem.release();
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            barSem.acquire();
            printBar.run();
            fooSem.release();
        }
    }
}

BlockingQueue 实现

import java.util.concurrent.SynchronousQueue;

class FooBar {
    private int n;
    private SynchronousQueue<Integer> fooQueue = new SynchronousQueue<>();
    private SynchronousQueue<Integer> barQueue = new SynchronousQueue<>();

    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            printFoo.run();          // 先打印
            barQueue.put(1);         // 通知Bar可以执行
            fooQueue.take();         // 等待Bar完成
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            barQueue.take();         // 等待Foo的打印完成
            printBar.run();          // 打印Bar
            fooQueue.put(1);         // 通知Foo可以继续
        }
    }
}

Condition实现

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class FooBar {
    private int n;
    private final Lock lock = new ReentrantLock();
    private final Condition fooCondition = lock.newCondition();
    private final Condition barCondition = lock.newCondition();

    private boolean fooCanRun = true;

    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.
            lock.lock();
            try {
                while (!fooCanRun) {
                    fooCondition.await();
                }
                printFoo.run();
                fooCanRun = false;
                barCondition.signal();
            } finally {
                lock.unlock();
            }
        }
    }

    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.
            lock.lock();
            try {
                while (fooCanRun) {
                    barCondition.await();
                }
                printBar.run();
                fooCanRun = true;
                fooCondition.signal();
            } finally {
                lock.unlock();
            }
        }
    }
}
posted @ 2025-07-25 20:59  又是火星人  阅读(3)  评论(0)    收藏  举报