当前位置: 首页 > news >正文

1115. 交替打印FooBar

1115. 交替打印FooBar

题目描述

我们提供一个类:

class FooBar {public void foo() {
    for (int i = 0; i < n; i++) {
      print("foo");
    }}public void bar() {
    for (int i = 0; i < n; i++) {
      print("bar");
    }}
}

两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。

请设计修改程序,以确保 "foobar" 被输出 n 次。

 

示例 1:

输入: n = 1
输出: "foobar"
解释: 这里有两个线程被异步启动。其中一个调用 foo() 方法, 另一个调用 bar() 方法,"foobar" 将被输出一次。

示例 2:

输入: n = 2
输出: "foobarfoobar"
解释: "foobar" 将被输出两次。

解法

Java

Condition 使用场景分析

使用单个 Condition 的情况:

  1. 简单交替执行

    • 线程间只需要简单的等待/唤醒机制
    • FooBar 问题中,两个线程轮流执行的场景
  2. 共享同一个等待条件

    • 多个线程基于相同的条件变量进行等待
    • 状态切换逻辑简单明确
  3. 性能要求不严格

    • 不需要精确控制唤醒特定线程
    • 可以接受所有等待线程都被唤醒的开销

使用多个 Condition 的情况:

  1. 复杂状态管理

    • 需要根据不同条件唤醒不同类型的线程
    • 多种不同的等待状态需要区分管理
  2. 性能优化需求

    • 避免 signalAll() 唤醒所有线程的性能损耗
    • 精确唤醒特定线程,减少不必要的线程调度
  3. 语义清晰性要求

    • 不同的 Condition 对象代表不同的等待语义
    • 代码可读性和维护性更好

实际建议:

  • 简单场景(如本题):使用单个 Condition 足够
  • 复杂场景(多个不同类型的消费者/生产者):建议使用多个 Condition
  • 性能敏感场景:优先考虑多个 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 Lock lock = new ReentrantLock();private Condition fooCondition = lock.newCondition();private Condition barCondition = lock.newCondition();private boolean fooTurn = true;public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {lock.lock();try {// 如果不是foo的回合,则等待while (!fooTurn) {fooCondition.await();}// printFoo.run() outputs "foo". Do not change or remove this line.printFoo.run();fooTurn = false; // 切换到bar的回合barCondition.signal(); // 唤醒bar线程} finally {lock.unlock();}}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {lock.lock();try {// 如果不是bar的回合,则等待while (fooTurn) {barCondition.await();}// printBar.run() outputs "bar". Do not change or remove this line.printBar.run();fooTurn = true; // 切换到foo的回合fooCondition.signal(); // 唤醒foo线程} finally {lock.unlock();}}}
}

Java

class FooBar {private int n;private boolean fooTurn = true; // true表示该foo执行,false表示该bar执行public FooBar(int n) {this.n = n;}public void foo(Runnable printFoo) throws InterruptedException {for (int i = 0; i < n; i++) {synchronized (this) {// 如果不是foo的回合,则等待while (!fooTurn) {wait();}// printFoo.run() outputs "foo". Do not change or remove this line.printFoo.run();fooTurn = false; // 切换到bar的回合notify(); // 唤醒一个等待的线程}}}public void bar(Runnable printBar) throws InterruptedException {for (int i = 0; i < n; i++) {synchronized (this) {// 如果不是bar的回合,则等待while (fooTurn) {wait();}// printBar.run() outputs "bar". Do not change or remove this line.printBar.run();fooTurn = true; // 切换到foo的回合notify(); // 唤醒一个等待的线程}}}
}

...


http://www.hskmm.com/?act=detail&tid=37129

相关文章:

  • 2025 年透气阀厂家最新推荐榜:深度剖析行业内优质企业技术实力与市场口碑,筛选高性能可靠品牌
  • 2025年10月AI搜索营销推荐:头部企业合作口碑榜
  • 函数编程(Leo)
  • P8060 [POI 2003] Sums
  • 2025年杭州电商代运营机构口碑榜:技术实力与成功案例深度分析
  • 【A】Sakura Tears
  • 资源分享--豪氏象棋教程
  • 2025年10月AI搜索营销推荐:主流服务商排行榜与避坑指南
  • 内网应用端口使用哪个范围的比较安全
  • 2025年10月AI搜索优化推荐:市场报告与全维度选择指南
  • Vue3+ts+pinia实现活跃的tab栏
  • 2025年10月AI搜索优化推荐:主流榜单对比与避坑指南
  • 排序算法学习笔记
  • 异常值检测算法学习
  • 2025 年国内喷雾干燥机最新推荐排行榜:聚焦优质品牌,助力企业精准选设备造粒/工业喷雾/陶瓷喷雾/制粒/奶粉喷雾干燥机厂家推荐
  • Python环境教程(一)-环境入门之pip conda
  • AI股票预测分析报告 - 2025年10月23日
  • SQL Server 2008 R2 升级补丁需要注意的问题
  • Maven的使用(Leo)
  • 标题
  • 数字化实战:医疗器械行业售后工程师如何借CRM实现高效运维​
  • 20251020_QQ_Cipher
  • 2025年10月geo优化服务商推荐:知名机构评测列表
  • 高压差分探头PKDV508E使用常见问题与解决方案
  • 好拼|免费在线拼图工具上架谷歌商店啦 - ops
  • 基于MATLAB/Simulink的光照强度模型构建方法
  • 地中海、双肩包、格子衫?从业9年程序员聊聊真实的程序员是什么样子
  • 2025年10月又红又痒用什么产品推荐:口碑排行五款精华评价
  • 卫星遥感技术在河湖监管中的应用
  • VonaJS AOP编程:魔术方法