Java多线程交替打印

news2024/11/18 18:33:58

多线程交互

在Java中,可以使用synchronized关键字或者java.util.concurrent包中的工具来实现多线程交替打印。以下是一个使用synchronized关键字的示例:

public class AlternatePrinting {

    private static final Object lock = new Object();

    private static Integer counter = 0;

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            while (counter <= 10) {
                synchronized (lock) {
                    if (counter % 2 == 0) {
                        System.out.println("t1:" + counter++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        });

        Thread t2 = new Thread(() -> {
            while (counter <= 10) {
                synchronized (lock) {
                    if (counter % 2 == 1) {
                        System.out.println("t2:" + counter++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }
        });
        t1.start();
        t2.start();
    }

}

运行效果:
在这里插入图片描述

以下是一个使用java.util.concurrent.locks.Condition的示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrinting {
    private static final Lock lock = new ReentrantLock();//定义了一个私有静态最终的`ReentrantLock`对象`lock`来实现同步

    //定义了两个`Condition`对象`condition1`和`condition2`,它们用于线程间的协调/通信。
    private static final Condition condition1 = lock.newCondition();
    private static final Condition condition2 = lock.newCondition();

    //定义了一个静态整型`counter`并初始化为1,用作计数器
    private static int counter = 1;

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            while (counter <= 9) {
                lock.lock();
                try {
                    while (counter % 2 == 0) {//如果计数器为偶数,则需要等待直到`condition1`接收到信号。
                        try {
                            condition1.await();//当前线程释放锁:调用`await()`方法的线程会释放与`Condition`关联的`Lock`,允许其他线程获得这个锁并执行它们的任务。
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    //`thread1`循环执行,只有当`counter<=19`且`counter`为奇数时,才打印`counter`的值,并将`counter`增加1。
                    System.out.println("Thread 1: " + counter++);

                    //唤醒等待:如果有任何线程正在等待与 `condition2` 关联的 `Lock` 上的 `condition2.await();`,则调用 `signal()` 方法会选择其中一个线程(如果有多个线程在等待)并通知它可以继续执行
                    condition2.signal();
                } finally {
                    lock.unlock();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            while (counter <= 9) {
                lock.lock();
                try {
                    while (counter % 2 == 1) {//如果计数器为奇数,则需要等待直到`condition2`接收到信号。
                        try {
                            condition2.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    //`thread2`循环执行,只有当`counter<=19`且`counter`为偶数时,才打印`counter`的值,并将`counter`增加1。
                    System.out.println("Thread 2: " + counter++);
                    condition1.signal();
                } finally {
                    lock.unlock();
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

运行效果:
在这里插入图片描述

总结

在这个示例中,我们使用了ReentrantLock和两个Condition对象来实现线程的交替执行。ReentrantLock是一个可重入的互斥锁,它提供了与synchronized关键字类似的功能,但更加灵活。Condition对象用于在锁的基础上实现线程的等待和唤醒。

在这个示例中,我们创建了两个线程,它们分别打印奇数和偶数。每个线程都有一个与之关联的Condition对象。当一个线程获得锁并检查到counter的值满足条件时,它会打印counter的值并增加counter,然后调用与之关联的Condition对象的signal()方法唤醒等待的线程。如果counter的值不满足条件,线程会调用与之关联的Condition对象的await()方法进入等待状态,释放锁以便其他线程可以执行。

这个示例中的两个线程会交替打印1到10之间的奇数和偶数。这种方法使用了java.util.concurrent包中的工具,提供了更好的性能和灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式之创建型模式---工厂模式

文章目录 工厂模式概述简单工厂简单工厂的代码实现简单工厂的使用简单工厂应用场景 工厂方法工厂方法模式的代码实现工厂方法的使用工厂方法应用场景 抽象工厂抽象工厂模式代码实现抽象工厂的使用方法抽象工厂模式的应用场景 总结 工厂模式概述 工厂模式从名字就能看出&#x…

【Java笔记】如何创建自己的注解+注解怎么用于反射+SpringBoot常见注解

文章目录 0. 为什么SpringBoot要整这么多注解&#xff1f;1. 一些基础知识1.1 什么是注解1.2 Java内置注解1.2.1 作用在代码上的注解1.2.2 作用在注解的注解&#xff08;元注解&#xff09;1.2.3 Java 7之后的新注解 1.3 注解的作用1.4 如何实现一个自己的注解&#xff1f;1.4.…

向量的求导

参考&#xff1a; 向量的求导 向量内积求导

如何提交已暂存的更改到本地仓库?

文章目录 如何提交已暂存的更改到本地Git仓库&#xff1f;步骤1&#xff1a;确认并暂存更改步骤2&#xff1a;提交暂存的更改到本地仓库 如何提交已暂存的更改到本地Git仓库&#xff1f; 在Git版本控制系统中&#xff0c;当你对项目文件进行修改后&#xff0c;首先需要将这些更…

Diffusion Model原理剖析

目录 前言1. DDPM演算法初览2. 图像生成模型共同目标3. VAE: Lower bound of l o g P ( x ) logP(x) logP(x)4. Diffusion Model背后的数学原理5. 为什么需要Sample?6. Diffusion Model的应用7. Diffusion Model成功的关键总结参考 前言 接着上篇文章 图像生成模型浅析&#…

四川古力未来科技抖音小店:科技新宠,购物新选择

在数字化浪潮席卷全球的今天&#xff0c;电商行业日新月异&#xff0c;新兴平台层出不穷。四川古力未来科技抖音小店&#xff0c;作为其中的佼佼者&#xff0c;凭借其独特的魅力和创新的服务模式&#xff0c;正逐渐成为消费者眼中的购物新宠。 一、四川古力未来科技抖音小店的独…

深度卷积神经网络的整体运行流程(以alexnet为例)

0.基础概念&#xff08;复习一下&#xff09; 1.小批量随机梯度下降 目的&#xff1a; 希望找到最佳的参数&#xff0c;使损失函数最小。 使损失函数对w求导&#xff08;b就是x等于1的w&#xff09;&#xff0c;一个小批次的/eta&#xff08;学习率&#xff09;*小批次的平均…

2024团体设计天梯赛之L1-101 别再来这么多猫娘了

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

上市公司数字化转型速度测-含代码及原始数据(2000-2022年)

数据来源&#xff1a;Wind数据库、企业年报时间跨度&#xff1a;2000-2022年 其中吴非、赵宸宇版本的数据是从2000到2022年&#xff1b;袁淳版本和李瑛玫版本的数据均是从2001-2022年。数据范围&#xff1a;上市公司数据指标&#xff1a;计算了三份测算数字化转型速度的数据。其…

Java中的构造器

即使在类中什么都不写也会自动的生成一个构造器 注意 使用new关键字是在调用构造器 如果定义了有参构造 那么就不会默认的走Person person new Person();如果没有自己手动的定义无参构造就不能使用 在idea中 用按键Altinsert可以快速生成有参、无参构造&#xff08;某些品牌的…

yolov8-obb旋转目标检测详细流程

一、数据标注 由于旋转目标标注与传统的目标检测标注有一定的区别&#xff0c;故使用roLabelImg或者labelimg2进行标注&#xff0c;以下标注软件选用的是roLabelImg。 roLabelImg下载地址&#xff1a;https://github.com/cgvict/roLabelImg 直接在原有的labelimg环境中使用roL…

宝塔面板国际版aaPanel 精简版安装

宝塔面板国际版aaPanel 精简版安装 很多人都知道宝塔面板&#xff0c;但不知道宝塔面板还有英文版&#xff0c;宝塔面板英文版不是单纯的宝塔面板的翻译&#xff0c;而是根据老外的使用习惯及国外的网络环境做了一定的优化&#xff0c; 比如&#xff1a;去掉了手机号验证、去…

关于淘宝API接口请求数据的靠谱方式,主要包括以下几个方面:

关于淘宝API接口请求数据的靠谱方式&#xff0c;主要包括以下几个方面&#xff1a; 了解API接口和请求方式&#xff1a; API接口采用通用的HTTP协议&#xff0c;支持GET、POST等多种请求方式。GET方法主要用于向指定资源发出请求并返回实体主体内容&#xff0c;如查询、菜单列…

PBR相关基础知识

文章目录 **核心理念****关键组件与参数****工作流程****优势****挑战与注意事项**实例展示 基于物理的渲染&#xff08;Physically Based Rendering, PBR&#xff09;是一种现代计算机图形学技术&#xff0c;它致力于通过模拟真实世界中光与物质相互作用的物理规律来生成高度逼…

JAVA学习笔记30(线程)

1.线程 1.线程的概念 1.线程是由进程创建的&#xff0c;是进程的一个实体 2.一个进程可以拥有多个线程 2.并发 ​ *同一时刻&#xff0c;多个任务交替执行&#xff0c;造成一种"貌似同时"的错觉&#xff0c;单核cpu实现的多任务就是并发 3.并行 ​ *同一时刻&…

Python的round与Excel的round不一样?

Python四舍五入怎么做 round()奇进偶舍round函数既不是“四舍五入”的原则&#xff0c;也不是“四舍六入无成双”的原则。 decimal round() 偶然发现python的round函数和excel的round函数对某些数据的处理结果不一致。有看到博主提到是奇进偶舍的方法&#xff0c;但经过验证和…

elementUi 日期选择器 组件禁止手输

添加:editable"false" <el-date-pickerv-model"formInline.EndTime"type"datetime"placeholder"选择结束时间"format"YYYY-MM-DD HH:mm:ss"value-format"YYYY-MM-DD HH:mm:ss":editable"false">&…

0 transformers入门,HuggingFace!

目录 1 了解 2 文本分类 1 了解 1 依赖安装 !pip install transformers -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 2 了解transformers 能做什么 from transformers.pipelines import SUPPORTED_TASKS SUPPORTED_TASKS.items()2 文本分类 我没外网所以…

[2024更新]如何从Android恢复已删除的相机照片?

相信大家都经历过Android手机误删相机图片的经历。您是否正在寻找一种可行的方法来挽救这些丢失的照片&#xff1f;如果这是你迫切想解决的问题&#xff0c;那么这篇文章绝对可以帮助你。然而&#xff0c;与其考虑如何从Android恢复已删除的相机照片&#xff0c;我们更愿意建议…

3D模型人物换装系统(五 模型核批之后模型uv不正确)模型UV不正确

3D模型人物换装系统&#xff08;五 模型核批之后模型uv不正确&#xff09;模型UV不正确 介绍展示Maya导入查看uvUnity中测试分析没合批为什么没有问题总结 介绍 最近在公司里给公司做模型优化合批的时候发现了模型的uv在合批之后无法正常展示&#xff0c;这里找了很多的原因&a…