同步三个线程

2023-11-24

在采访中被问到这个问题,试图解决它......但没有成功。 我想到使用 CyclicBarrier

有三个线程 T1 打印 1,4,7... T2 打印 2,5,8...,T3 打印 3,6,9 ...。如何同步这三个来打印序列 1,2,3,4,5,6,7,8,9...

我尝试编写并运行以下代码

public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cBarrier = new CyclicBarrier(3);
        new Thread(new ThreadOne(cBarrier,1,10,"One")).start();
        new Thread(new ThreadOne(cBarrier,2,10,"Two")).start();
        new Thread(new ThreadOne(cBarrier,3,10,"Three")).start();
    }
}

class ThreadOne implements Runnable {
    private CyclicBarrier cb;
    private String name;
    private int startCounter;
    private int numOfPrints;

    public ThreadOne(CyclicBarrier cb, int startCounter,int numOfPrints,String name) {
        this.cb = cb;
        this.startCounter=startCounter;
        this.numOfPrints=numOfPrints;
        this.name=name;
    }

    @Override
    public void run() {
        for(int counter=0;counter<numOfPrints;counter++)
        {
            try {
            // System.out.println(">>"+name+"<< "+cb.await());
            cb.await();
            System.out.println("["+name+"] "+startCounter);
            cb.await();
            //System.out.println("<<"+name+">> "+cb.await());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        startCounter+=3;
        }
    }

}

output

[Three] 3
[One] 1
[Two] 2
[One] 4
[Two] 5
[Three] 6
[Two] 8
[One] 7
[Three] 9
[One] 10
[Two] 11
[Three] 12
[Two] 14
[One] 13
[Three] 15
[One] 16
[Two] 17
[Three] 18
[Two] 20
[One] 19
[Three] 21
[One] 22
[Two] 23
[Three] 24
[Two] 26
[One] 25
[Three] 27
[One] 28
[Two] 29
[Three] 30

谁能帮我给出正确答案吗?

类似的问题线程同步 - 同步三个线程打印 012012012012..... 不起作用


正如其他人已经提到的,CyclicBarrier 并不是完成该任务的最佳工具。

我还同意这样的观点:解决方案是将线程链接起来,并让一个线程始终为下一个线程设置权限。

这是使用信号量的实现:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.Semaphore;

public class PrintNumbersWithSemaphore implements Runnable {

private final Semaphore previous;

private final Semaphore next;

private final int[] numbers;

public PrintNumbersWithSemaphore(Semaphore previous, Semaphore next, int[] numbers) {
    this.previous = previous;
    this.next = next;
    this.numbers = numbers;
}

@Override
public void run() {

    for (int i = 0; i < numbers.length; i++) {
        wait4Green();

        System.out.println(numbers[i]);

        switchGreen4Next();
    }
}

private void switchGreen4Next() {
        next.release();
}

private void wait4Green() {
    try {
        previous.acquire();
    } catch (InterruptedException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
    Semaphore sem1 = new Semaphore(1);
    Semaphore sem2 = new Semaphore(1);
    Semaphore sem3 = new Semaphore(1);
    sem1.acquire();
    sem2.acquire();
    sem3.acquire();
    Thread t1 = new Thread(new PrintNumbersWithSemaphore(sem3, sem1, new int[] { 1, 4, 7 }));
    Thread t2 = new Thread(new PrintNumbersWithSemaphore(sem1, sem2, new int[] { 2, 5, 8 }));
    Thread t3 = new Thread(new PrintNumbersWithSemaphore(sem2, sem3, new int[] { 3, 6, 9 }));
    t1.start();
    t2.start();
    t3.start();
    sem3.release();

    t1.join();
    t2.join();
    t3.join();
}

}

这是另一个,在我看来,使用 CyclicBarrier 的实现相当麻烦:

import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier;

public class PrintNumbersWithCyclicBarrier implements Runnable {

private final CyclicBarrier previous;

private final CyclicBarrier next;

private final int[] numbers;

public PrintNumbersWithCyclicBarrier(CyclicBarrier previous, CyclicBarrier next, int[] numbers) {
    this.previous = previous;
    this.next = next;
    this.numbers = numbers;
}

@Override
public void run() {

    for (int i = 0; i < numbers.length; i++) {
        wait4Green();

        System.out.println(numbers[i]);

        switchRed4Myself();

        switchGreen4Next();
    }
}

private void switchGreen4Next() {
    try {
        next.await();
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

private void switchRed4Myself() {
    previous.reset();
}

private void wait4Green() {
    try {
        previous.await();
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

static public void main(String argv[]) throws InterruptedException, BrokenBarrierException {
    CyclicBarrier cb1 = new CyclicBarrier(2);
    CyclicBarrier cb2 = new CyclicBarrier(2);
    CyclicBarrier cb3 = new CyclicBarrier(2);
    Thread t1 = new Thread(new PrintNumbersWithCyclicBarrier(cb3, cb1, new int[] { 1, 4, 7 }));
    Thread t2 = new Thread(new PrintNumbersWithCyclicBarrier(cb1, cb2, new int[] { 2, 5, 8 }));
    Thread t3 = new Thread(new PrintNumbersWithCyclicBarrier(cb2, cb3, new int[] { 3, 6, 9 }));
    t1.start();
    t2.start();
    t3.start();
    cb3.await();

    t1.join();
    t2.join();
    t3.join();
}

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

同步三个线程 的相关文章

  • Windows 上的虚假唤醒。是否可以?

    我最近学习了 虚假唤醒 有人说这个问题只可能发生在某些类型的 Linux PC 上 我用的是窗户 我为虚假唤醒编写了测试 我得到的结果是这是可能的 但我想向您展示这个测试 也许我在某个地方犯了错误 我的初始变体 import java ut
  • 面试问题 - 在排序数组 X 中搜索索引 i,使得 X[i] = i

    昨天面试时 我被问到了以下问题 考虑一个 Java 或 C 数组X它已排序并且其中没有两个元素是相同的 如何最好地找到索引i这样该索引处的元素也是i 那是X i i 作为澄清 她还给了我一个例子 Array X 3 1 0 3 5 7 in
  • Android 上的 setTimeOut() 相当于什么?

    我需要等效的代码setTimeOut call function milliseconds 对于安卓 setTimeOut call function milliseconds 您可能想查看定时任务 http developer andro
  • mvn dependency:analyze 结果不正确

    我一直在寻找一种工具 它能够向您显示未使用的依赖项 我很快就偶然发现了 Maven 命令mvn dependency analyze 这样做的问题是 它经常检测到 未使用的 依赖项 如果缺失 这些依赖项就会导致构建失败 这是优化项目的示例
  • 使用 ScheduledExecutorService 安排每月任务

    我想在该月的某一天的特定时间安排一项任务 每次运行之间的间隔可以设置在 1 到 12 个月之间 在java中 可以使用ScheduledExecutorService以固定的时间间隔调度任务 既然一个月的天数不固定 那么如何实现呢 提前致谢
  • 简单的 C++ 线程

    我正在尝试在 C Win32 中创建一个线程来运行一个简单的方法 我是 C 线程的新手 但对 C 中的线程非常熟悉 这是我想做的一些伪代码 static void MyMethod int data RunStuff data void R
  • x.person 上的 @OneToOne 或 @ManyToOne 引用未知实体:y.Person - 继承问题

    我的 Hibernate 架构有问题 我有一个 MappedSuperClass 人员 一名员工和一名客户 gt Person class MappedSuperclass Audited public class Person exten
  • 如何提高 Guice 启动时的性能

    好吧 我知道我的计算不客观等等 但无论如何 我讨厌在执行单元测试时等待这么多时间 我的 guice swing 应用程序需要大约 7 秒来初始化 这是一个简单的 IRC 客户端 在那一刻 没有打开连接 我什至还没有调用任何 java io
  • 从外部 clojar 导入/使用资源

    我想做的是将一个大文件 MIDI 声音字体 打包到一个独立的 Maven repo clojar 中 然后能够以编程方式将其拉下来并从单独的项目中使用它 事实证明 这个看似简单的任务比我想象的要复杂 理想的情况是 如果有一种方法可以直接访问
  • 序言中不允许引用

    请帮我找到这个异常的原因 我使用以下罐子 core renderer jar itext paulo 155 jar 第一个文档 xhtml lt xml version 1 0 encoding UTF 8 gt lt DOCTYPE h
  • 如何在最短的时间内克隆java中的输入流

    有人可以告诉我如何克隆输入流 并花费尽可能少的创建时间吗 我需要多次克隆输入流以使用多种方法来处理 IS 我尝试了三种方法 但由于这样或那样的原因 事情不起作用 方法 1 感谢 stackoverflow 社区 我发现以下链接很有帮助 并将
  • JFreeChart MeterPlot

    我目前正在用java做Agent项目 在某些时候 我需要显示一个仪表 例如 电池电量 我的程序中有 5 个代理 每个代理都会创建自己的带有名称的仪表图 但不知何故他们没有更新数据集 或者他们正在更新数据集 只是它没有显示在仪表图上 任何想法
  • 如何迭代SparseArray?

    有没有办法迭代 Java SparseArray 适用于 Android 我用了sparsearray通过索引轻松获取值 我找不到 看来我找到了解决方案 我没有正确注意到keyAt index 功能 所以我会这样做 for int i 0
  • 从 Perl 线程生成 Expect

    我正在编写一个脚本 该脚本需要定期 每 5 分钟 生成一个 Expect 进程来完成一些工作 下面是我的代码 它生成一个 Expect 进程并执行一些工作 脚本的主要进程始终在做一些其他工作 例如它可能等待用户输入 因为我在一个线程中调用这
  • java.lang.NoSuchMethodError:com.fasterxml.jackson.databind.type。使用 apache beam Spark runner 运行 go 示例时

    我想跑grades https github com apache beam tree master sdks go examples gradesapache beam go sdk 提出的示例 在一个主服务器和两个从服务器 spark2
  • 仅在java中使用数组计算50的阶乘

    我是java的初学者 我有一个作业要编写一个完整的程序 使用数组计算 50 的阶乘 我无法使用像 biginteger 这样的任何方法 我只能使用数组 因为我的教授希望我们理解背后的逻辑 我猜 然而 他并没有真正教我们数组的细节 所以我在这
  • Spring Boot 健康执行器 - 什么时候上线?

    我找不到任何有关 Springs Health Actuator 何时返回 UP 状态的文档 你能依靠一切吗 Components正在初始化 会不会 Controller准备好满足请求了吗 为了测试应用程序上下文是否已加载 您可以执行此自定
  • 如何在 SpringDoc OpenAPI 3 中引用文件?

    我有 Spring Boot 项目 我想在其中记录我的 API 这里是正在处理的 Web 服务的示例 ApiResponses value ApiResponse responseCode 200 content Content media
  • 文件构造函数说明

    我无法理解以下文件构造函数 public File String parent String child and public File File parent String child 参数有什么作用parent and child该文件
  • Spring JMS开始根据请求监听jms队列

    Spring提供 JMSListener用于监听来自特定队列的消息的注释 还有一个替代方案实施JmsListenerConfigurer http docs spring io spring docs current spring fram

随机推荐

  • 无法调整react-chartjs-2圆环图的大小

    我正在尝试使用 React 和 gatsbyjs 制作一个圆环图 该图表工作正常 但我无法让它使用 div 的完整宽度 对于保留的区域来说 它显示的太小 render return
  • 扩展 Django Flatpages 以接受模板标签

    我在我们网站上的很多内容中使用了 django 平面页面 我想扩展它以接受内容中的 django 模板标签 我找到了这个snippet但经过一番嬉笑之后 我无法让它发挥作用 我是否正确地假设您需要对 django 平面应用程序进行 子类化
  • 我在命令提示符中看到一个问号,而不是货币符号

    我使用 Windows 7 Visual Studio 2013 C 和 NET 4 5 我的问题是下面一行的输出 Console WriteLine Car s value 0 C myNewCar determineMarketValu
  • 我怎样才能知道c中指针变量分配的内存大小[重复]

    这个问题在这里已经有答案了 我在这种情况下遇到了一些问题 您能请您提供一下想法吗 main char p NULL p char malloc 2000 sizeof char printf size of p d n sizeof p 在
  • => 在 Linq 表达式中意味着什么 [重复]

    这个问题在这里已经有答案了 虽然这是一个重复的问题 但我以前从未在代码中见过表达式 gt 如果我知道这是一个 lambda 表达式 我就会用 google 搜索并自己找出答案 谢谢 我是 Linq 的新手 所以当我在这段代码中遇到 gt 时
  • 如何制作 Django 查询集来选择组内具有最大值的记录

    这是我的 Django 类 class MyClass models Model my integer models IntegerField created ts models DateTimeField default datetime
  • 在 Python 中查找箭头键的值:为什么它们是三元组?

    我正在尝试查找本地系统分配给箭头键的值 特别是在 Python 中 我正在使用以下脚本来执行此操作 import sys tty termios class Getch def call self fd sys stdin fileno o
  • 如何防止 Excel 在宏计算时渲染电子表格?

    我的宏用数字更新一个大型电子表格 但它运行速度非常慢 因为 Excel 在计算时渲染结果 如何在宏完成之前阻止 Excel 渲染输出 我使用了两种建议的解决方案 Application ScreenUpdating False Applic
  • 如何在 thymeleaf 中处理和连接字符串

    我有一个字符串列表 这是我感兴趣的属性名称 我想连接这些字符串的值 但不使用属性名称 而是使用它们的属性值 我看到起点是 strings listJoin 但是我怎么能说将列表中的元素与属性文件中的值相匹配呢 该列表将是 name addr
  • 创建一个可根据其内容调整大小的 QDockWidget

    我有一个应用程序 需要在运行时根据用户输入以编程方式将固定大小的子窗口小部件添加到停靠窗口小部件 我想将这些小部件添加到 Qt RightDockArea 上的停靠栏 从上到下直到空间不足 然后创建一个新列并重复 本质上与流程布局示例相反
  • cpp中的“[=]”是什么意思

    请检查下面的代码 NodeScheduleLambda this 0 01f this gt removeFromParentAndCleanup true 那里面的 是什么意思呢 有谁可以帮帮我吗 谢谢 lambda 是一种未命名 匿名函
  • NewDirectByteBuffer 是否在本机代码中创建副本

    我正在 C 中创建两个数组 这两个数组将在 java 端读取 env gt NewDirectByteBuffer env gt NewByteArray 这些函数会复制我发送的缓冲区吗 我是否需要在 C 端的堆上创建缓冲区 或者是否可以在
  • Selenium IDE:如何在未找到元素或出现错误时继续执行脚本

    我需要你的帮助 我只想在 Firefox 上继续我的 Selenium IDE 脚本 即使出现错误或未找到元素 我正在使用 HTML 格式的脚本 在下一个命令中使用该元素之前 您必须显式检查该元素是否存在 这可能会导致错误并中断脚本的执行
  • HTTP 请求失败! HTTP/1.1 503 服务暂时不可用

    我正在使用函数 file get contents 从网页获取内容 有些网站运行良好 但大多数都给我这个错误 failed to open stream HTTP request failed HTTP 1 1 503 Service Te
  • 具有不同文本大小的 TextView

    是否可以在一个 TextView 中设置不同的 textSize 我知道我可以使用以下方法更改文本样式 TextView textView TextView findViewById R id textView Spannable span
  • 防止堆上未对齐的数据

    我正在构建一个使用 SSE 内在函数的类层次结构 因此该类的一些成员需要 16 字节对齐 对于堆栈实例我可以使用 declspec align 像这样 typedef declspec align 16 float Vector 4 cla
  • Azure 容器应用程序每 30 秒重新启动一次

    我有一个基于的 Azure 容器应用程序托管后台服务模型 它本质上只是一个长期运行的控制台应用程序 它覆盖了BackgroundService ExecuteAsync方法并等待停止信号 通过传递的取消令牌 当我在 Docker 中本地运行
  • 在 jQuery 中,将数字格式化为小数点后两位的最佳方法是什么?

    这就是我现在所拥有的 number val parseFloat number val toFixed 2 我觉得很乱 我认为我没有正确链接这些函数 我是否必须为每个文本框调用它 或者我可以创建一个单独的函数吗 如果您要对多个领域执行此操作
  • 与区域设置无关的 strtod 实现

    我有一个库需要解析始终使用点 的双数 作为小数点分隔符 不幸的是 对于这种情况 strtod 尊重可能使用不同分隔符的语言环境 因此解析可能会失败 我无法 setlocale 它不是线程安全的 所以我现在正在寻找一个干净的独立于语言环境的
  • 同步三个线程

    在采访中被问到这个问题 试图解决它 但没有成功 我想到使用 CyclicBarrier 有三个线程 T1 打印 1 4 7 T2 打印 2 5 8 T3 打印 3 6 9 如何同步这三个来打印序列 1 2 3 4 5 6 7 8 9 我尝试