Java CyclicBarrier错误使用的实例

 更新时间:2025年01月26日 10:35:26   作者:学亮编程手记  
文章描述了一个Java程序使用CyclicBarrier实现两个线程交替打印字母和数字时遇到的问题,由于线程执行顺序不当,导致输出结果与预期不符,通过调整线程的等待和打印顺序,解决了问题,文章还提供了一个控制流图来详细解释修改前后的程序逻辑

Java CyclicBarrier错误使用

错误代码示例

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

public class AlternatePrintCyclicBarrier {

    private static final CyclicBarrier barrier = new CyclicBarrier(2);

    public static void main(String[] args) {
        String letters = "abcd";
        String numbers = "1234";

        Thread letterThread = new Thread(() -> {
            for (char letter : letters.toCharArray()) {
                try {
                    System.out.print(letter);
                    barrier.await(); // 等待另一个线程
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        Thread numberThread = new Thread(() -> {
            for (char number : numbers.toCharArray()) {
                try {
                    barrier.await(); // 等待字母线程
                    System.out.print(number);
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        letterThread.start();
        numberThread.start();

        try {
            letterThread.join();
            numberThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

代码错误分析

当前代码的逻辑是两个线程交替打印字母和数字,但是由于CyclicBarrier的使用不当,导致输出结果为ab12cd34。

具体原因是在字母线程中先打印字母再等待,而在数字线程中先等待再打印数字,这会导致字母线程先打印两个字母后,数字线程才开始打印。

修改方案

为了实现交替打印的效果,可以调整线程的执行顺序。

具体来说,可以让字母线程先等待,然后打印字母;而数字线程先等待,然后打印数字。这样可以确保两个线程交替执行。

修改后的代码

package com.zxl.a1b2c3d4;

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

public class AlternatePrintCyclicBarrier {

    private static final CyclicBarrier barrier = new CyclicBarrier(2);

    public static void main(String[] args) {
        String letters = "abcd";
        String numbers = "1234";

        Thread letterThread = new Thread(() -> {
            for (char letter : letters.toCharArray()) {
                try {
                    barrier.await(); // 等待数字线程
                    System.out.print(letter);
                    barrier.await(); // 等待数字线程
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        Thread numberThread = new Thread(() -> {
            for (char number : numbers.toCharArray()) {
                try {
                    barrier.await(); // 等待字母线程
                    System.out.print(number);
                    barrier.await(); // 等待字母线程
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        letterThread.start();
        numberThread.start();

        try {
            letterThread.join();
            numberThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

修改后的控制流图

详细解释

  • Start:程序开始。
  • CreateThreads:创建两个线程,一个用于打印字母,一个用于打印数字。
  • StartThreads:启动这两个线程。
  • WaitThreads:主线程调用join方法等待两个子线程执行完毕。
  • End:程序结束。

在子图中:

字母线程

  • AwaitNumber1:等待数字线程。
  • PrintLetter:打印字母。
  • AwaitNumber2:等待数字线程。
  • 循环执行上述步骤。

数字线程

  • AwaitLetter1:等待字母线程。
  • PrintNumber:打印数字。
  • AwaitLetter2:等待字母线程。
  • 循环执行上述步骤。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • idea 无法debug调试的解决方案

    idea 无法debug调试的解决方案

    这篇文章主要介绍了idea 无法debug调试的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 深入解析Java编程中final关键字的作用

    深入解析Java编程中final关键字的作用

    final关键字正如其字面意思一样,意味着最后,比如被final修饰后类不能集成、变量不能被再赋值等,以下我们就来深入解析Java编程中final关键字的作用:
    2016-06-06
  • Java判断闰年的2种方法示例

    Java判断闰年的2种方法示例

    这篇文章主要给大家介绍了关于Java判断闰年的2种方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Java实现Excel与TXT文本的高效互转

    Java实现Excel与TXT文本的高效互转

    在日常开发中,我们经常需要在不同的数据存储格式之间进行转换,本文将分享如何在 Java 中高效实现 Excel 与 TXT 的互转,有需要的小伙伴可以了解下
    2025-09-09
  • Linux系统中查询JDK安装目录的几种常用方法

    Linux系统中查询JDK安装目录的几种常用方法

    这篇文章主要介绍了Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目录搜索,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-07-07
  • springcloud alibaba nacos config无法加载配置文件的解决方案

    springcloud alibaba nacos config无法加载配置文件的解决方案

    这篇文章主要介绍了springcloud alibaba nacos config无法加载配置文件的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • 详解Java如何利用位操作符创建位掩码

    详解Java如何利用位操作符创建位掩码

    在本文中,我们来看看如何使用位操作符实现低级别的位掩码。我们将看到我们如何将一个单一的int变量作为一个单独的数据容器,感兴趣的可以跟随小编一起学习一下
    2022-10-10
  • Hibernate映射解析之关联映射详解

    Hibernate映射解析之关联映射详解

    所谓关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用。下面这篇文章详细的给大家介绍了Hibernate映射解析之关联映射的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • Mybatis查询语句结果集的总结大全

    Mybatis查询语句结果集的总结大全

    这篇文章主要给大家总结介绍了关于Mybatis查询语句结果集的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • Java基于代理模式解决红酒经销问题详解

    Java基于代理模式解决红酒经销问题详解

    这篇文章主要介绍了Java基于代理模式解决红酒经销问题,详细描述了代理模式的概念、原理并结合实例形式分析了java基于代理模式解决红酒经销问题的相关步骤、实现方法与操作注意事项,需要的朋友可以参考下
    2018-04-04

最新评论