Java CyclicBarrier错误使用的实例

 更新时间:2025年01月03日 11:00:00   作者:学亮编程手记  
文章描述了一个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:等待字母线程。
  • 循环执行上述步骤。

总结

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

相关文章

  • springboot的统一异常处理,使用@RestControllerAdvice详解

    springboot的统一异常处理,使用@RestControllerAdvice详解

    @RestControllerAdvice是Spring Boot中的全局异常处理注解,结合了@ControllerAdvice和@ResponseBody的功能,通过创建自定义异常类和全局异常处理器,可以实现统一异常处理,确保API的一致性和响应的标准化
    2024-12-12
  • org.apache.zookeeper.KeeperException.BadVersionException异常的解决

    org.apache.zookeeper.KeeperException.BadVersionException异常的解

    在使用Apache ZooKeeper进行分布式协调时,你可能会遇到org.apache.zookeeper.KeeperException.BadVersionException异常,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2024-03-03
  • Java实现无头双向链表操作

    Java实现无头双向链表操作

    这篇文章主要为大家详细介绍了Java实现无头双向链表的基本操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 如何解决SpringBoot集成百度UEditor图片上传后直接访问404

    如何解决SpringBoot集成百度UEditor图片上传后直接访问404

    在本篇文章里小编给大家整理的是一篇关于如何解决SpringBoot集成百度UEditor图片上传后直接访问404相关文章,需要的朋友们学习下。
    2019-11-11
  • Java日常练习题,每天进步一点点(64)

    Java日常练习题,每天进步一点点(64)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-09-09
  • SpringBoot项目的logback日志配置(包括打印mybatis的sql语句)

    SpringBoot项目的logback日志配置(包括打印mybatis的sql语句)

    这篇文章主要介绍了SpringBoot项目的logback日志配置(包括打印mybatis的sql语句),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • spring boot 自定义参数过滤器,把传入的空字符转换成null方式

    spring boot 自定义参数过滤器,把传入的空字符转换成null方式

    这篇文章主要介绍了spring boot 自定义参数过滤器,把传入的空字符转换成null方式。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 利用java制作一个小的目录查询器的方法

    利用java制作一个小的目录查询器的方法

    下面小编就为大家带来一篇利用java制作一个小的目录查询器的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 深入探索Java常量池

    深入探索Java常量池

    这篇文章主要介绍了深入探索Java常量池,涉及静态常量池和运行时常量池的介绍,常量池的好处,8种基本数据类型的包装类和常量池等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • MyBatis-Plus Page 分页不生效的问题解决

    MyBatis-Plus Page 分页不生效的问题解决

    分页是常见的一种功能,本文主要介绍了MyBatis-Plus Page分页不生效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07

最新评论