LeetCode 1115. 交替打印 FooBar

题目描述

1115. 交替打印 FooBar

思路分析

解法一:信号量控制(推荐)

核心思路

  • 使用两个信号量控制打印顺序:foo 先执行、bar 后执行。
  • foo 打印后释放 barbar 打印后释放 foo
  • 重复 n 次即可形成严格交替。


复杂度分析

  • 时间复杂度:O(n),其中 n 表示打印次数。
  • 空间复杂度:O(1),仅使用常数额外空间。
import java.util.concurrent.Semaphore;

class FooBar {
    private int n;
    private final Semaphore fooSem = new Semaphore(1);
    private final Semaphore barSem = new Semaphore(0);

    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();
        }
    }
}
type FooBar struct {
	n      int
	fooSem chan struct{}
	barSem chan struct{}
}

func Constructor(n int) FooBar {
	fb := FooBar{
		n:      n,
		fooSem: make(chan struct{}, 1),
		barSem: make(chan struct{}, 1),
	}
	fb.fooSem <- struct{}{}
	return fb
}

func (fb *FooBar) Foo(printFoo func()) {
	for i := 0; i < fb.n; i++ {
		<-fb.fooSem
		printFoo()
		fb.barSem <- struct{}{}
	}
}

func (fb *FooBar) Bar(printBar func()) {
	for i := 0; i < fb.n; i++ {
		<-fb.barSem
		printBar()
		fb.fooSem <- struct{}{}
	}
}

相似题目

题目 难度 考察点
1114. 按序打印 简单 多线程
1116. 打印零与奇偶数 中等 多线程
1117. H2O 生成 中等 多线程
1195. 交替打印字符串 中等 多线程
1226. 哲学家进餐 中等 多线程
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/61612197
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!