线程通信例子

news2025/1/22 13:13:25

 

目录

线程通信的例子:使用两个线程打印1-100。线程1,线程2,交替打印

涉及的3个方法:

 运行结果:

把锁改为其他对象

运行结果报错:

改进,把notify和wait的调用者改为obj 

sleep()和wait()的异同?


 

线程通信的例子:使用两个线程打印1-100。线程1,线程2,交替打印

涉及的3个方法:

wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器
 notify():一旦执行此方法,就会唤醒wait的一个线程。如果有多个线程被wait,就会唤醒优先级高的线程
notifyAll():一旦执行此方法,就会唤醒所有被wait的线程

 说明:
1. wait(),notify(),notifyAll(),3个方法必须使用在同步代码块或同步方法中。 

2.wait(),notify(),notifyAll(),3个方法的调用者必须是同步代码块或者同步方法中的同步监视器(锁),否则会出现IllegalMonitorStateException

3. wait(),notify(),notifyAll()3个方法都是定义在java.lang.Object类中

class Number implements Runnable{

	private int number=1;
	
	@Override
	public void run() {
		while(true) {
			
//			this是当前类的对象,在本例中,this是nb
			synchronized (this) {
			
				this.notifyAll();
			if(number<=100) {
				
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				System.out.println(Thread.currentThread().getName()+":"+number);
				number++;
				
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}else {
				break;
			}
			
			}
		}
	}
}


public class CommunicationTest {

	public static void main(String[] args) {
		Number nb=new Number();
		
		Thread th1=new Thread(nb);
		Thread th2=new Thread(nb);
		
		th1.setName("线程1");
		th2.setName("线程2");
		
		th1.start();
		th2.start();
	}
}

 运行结果:

线程1:1
线程2:2
线程1:3
线程2:4
线程1:5

.............

线程1:95
线程2:96
线程1:97
线程2:98
线程1:99
线程2:100

把锁改为其他对象

 把synchronized(this)改为synchronized (obj)

class Number implements Runnable{

	private int number=1;
	public Object obj=new Object();
	@Override
	public void run() {
		while(true) {
			
//			this是当前类的对象,在本例中,this是nb
			synchronized (obj) {
			
				this.notifyAll();
			if(number<=100) {
				
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				System.out.println(Thread.currentThread().getName()+":"+number);
				number++;
				
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}else {
				break;
			}
			
			}
		}
	}
}

public class CommunicationTest {

	public static void main(String[] args) {
		Number nb=new Number();
		
		Thread th1=new Thread(nb);
		Thread th2=new Thread(nb);
		
		th1.setName("线程1");
		th2.setName("线程2");
		
		th1.start();
		th2.start();
	}
}

运行结果报错:

Exception in thread "线程2" Exception in thread "线程1" java.lang.IllegalMonitorStateException

改进,把notify和wait的调用者改为obj 

class Number implements Runnable{

	private int number=1;
	public Object obj=new Object();
	@Override
	public void run() {
		while(true) {
			

			synchronized (obj) {
			
				obj.notifyAll();
			if(number<=100) {
				
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
				System.out.println(Thread.currentThread().getName()+":"+number);
				number++;
				
				try {
					obj.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}else {
				break;
			}
			
			}
		}
	}
}


public class CommunicationTest {

	public static void main(String[] args) {
		Number nb=new Number();
		
		Thread th1=new Thread(nb);
		Thread th2=new Thread(nb);
		
		th1.setName("线程1");
		th2.setName("线程2");
		
		th1.start();
		th2.start();
	}
}

sleep()和wait()的异同?

1.相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。

2.不同点:(1)两个方法声明的位置不同:Thread类中声明sleep(),Object 类中声明wait()

(2)调用的要求不同,sleep()可以在任何需要的场景下调用,wait()必须使用在同步代码块或者同步方法中

(3)是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep不会释放锁,wait()会释放锁 

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

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

相关文章

【数据结构】—— Java实现单链表

Java实现单链表一、一链表的概念及结构二、头节点与头指针的异同三、代码实现一、一链表的概念及结构 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 注意&#xff1a; 从上图可以看出&#xff0c;链式结构在逻…

MobPush for SDK API

推送监听接口 (addPushReceiver) 描述&#xff1a;添加推送监听&#xff0c;可监听接收到的自定义消息(透传消息)、通知消息、通知栏点击事件、别名和标签变更操作。 /*** com.mob.pushsdk.MobPush.class* MobPush推送监听接口* param receiver 监听*/ public static void ad…

Databend 开源周报 #74

Databend 是一款强大的云数仓。专为弹性和高效设计&#xff0c;自由且开源。 即刻体验云服务&#xff1a;https://app.databend.com。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements Meta watch client …

【Word2021交叉引用参考文献格式】

Word2021交叉引用参考文献格式1 格式分类2 格式设置方法2.1 引用单个参考文献2.2 引用连续两个参考文献2.3 引用连续三个及三个以上的参考文献1 格式分类 按照引用参考文献的数量&#xff0c;格式一般分为三种&#xff1a; 1、引用单个参考文献&#xff0c;样例&#xff1a;我…

Leetcode回溯法题解

第一题 17. 电话号码的字母组合 题目描述&#xff1a;给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按任意顺序返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例1&#xff1a;…

Linux yum 使用手册,以及内网源搭建

Linux yum 内网源搭建 序 在 Linux 中&#xff0c;我们经常安装各个开源网站编写的代码、软件&#xff0c;在安装的时候各个软件之间有各种依赖关系&#xff0c;还可能出现版本问题&#xff0c;比如 Centos7 支持的软件&#xff0c; Centos6 就未必支持。如果是 Java 开发应该…

ArcGIS基础实验操作100例--实验73创建闭合线内部缓冲区

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验73 创建闭合线内部缓冲区 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff0…

K8S ReplicaSet 原理 示例 HPA扩容

K8S ReplicaSet 基本使用 K8S ReplicaSet 对象的作用是在任意时间点保持一组稳定的副本Pod运行&#xff0c;因此&#xff0c;它通常用于保证指定数量的相同Pod的可用性。乍一看&#xff0c; ReplicaSet 对象的定义跟 Replication Controller 并没有什么区别&#xff0c;都是维…

AI检测人员工衣工服着装不规范识别系统 yolo

AI检测人员工衣工服着装不规范识别系统基于opencvyolo网络深度学习模型对现场画面中人员着装穿戴实时监测分析。我们使用YOLO(你只看一次)算法进行对象检测。YOLO是一个聪明的卷积神经网络(CNN)&#xff0c;用于实时进行目标检测。该算法将单个神经网络应用于完整的图像&#x…

Vivado综合属性之SRL_STYLE

本文介绍综合属性SRL_STYLE取register、srl、srl_reg、reg_srl、reg_srl_reg和block中的值时&#xff0c;对Schematic的影响。 SRL_STYLE用于指导Vivado将SRL&#xff08;移位寄存器&#xff09;映射为何种形式。 目录 默认值 测试代码 原理图 SRL_STYLE配置为register …

【JavaSE】String类

目录 前言&#xff1a; 1.1、了解字符串构造方法 1.2、求字符串长度&#xff08;xxx.length()&#xff09; 1.3、isEmpty()方法 1.4、String对象的比较 1.4.1、通过&#xff08;str1 str2&#xff09;来比较&#xff0c;这样比较的是两个引用当中的地址 1.4.2、 boolea…

【ONE·C++ || vector (一)】

总言 学习笔记&#xff0c;慢慢补充。 文章目录总言1、整体介绍&#xff1a;2、常用各种接口介绍2.1、vector的基本结构&#xff1a;构造、析构、赋值2.1.1、总体情况预览2.1.2、各项函数使用演示2.2、vector增删查改相关2.2.1、增删查改总览2.2.2、如何在vector中插入、删除、…

Kotlin之使用协程编写高效的并发程序

文章目录1.协程的基本用法2.更多的作用域构建器3.使用协程简化回调的写法协程属于Kotlin中非常有特色的一项技术&#xff0c;因为大部分编程语言中是没有协程这个概念的。那么什么是协程呢&#xff1f;它其实和线程有点相似&#xff0c;可以简单地将它理解成一种轻量级的线程。…

Linux学习入门

1、Linux简介 操作系统分类&#xff1a;桌面操作系统、、服务器操作系统、移动端操作系统、嵌入式操作系统桌面操作系统主要针对个人电脑&#xff0c;Linux在桌面操作系统的应用主要有国产操作系统&#xff0c;Ubuntu。服务器操作系统有windows和linux以及苹果&#xff0c;主流…

微信小程序是如何实现快速编译的?

过往中小企业或技术团队开发一个 App 的时间成本和人力成本居高难下&#xff0c;但是随着微信上线小程序&#xff0c;更像是为这部分群体打开了一扇天窗&#xff0c;此后小程序呈现出井喷式发展的状态&#xff0c;不仅微信&#xff0c;支付宝、百度、抖音等超级 App 都跟上步伐…

线程进阶

常见的锁策略乐观锁 vs 悲观锁乐观锁&#xff1a;预测锁竞争不是很激烈悲观锁&#xff1a;预测锁竞争会很激烈轻量级锁 vs 重量级锁轻量级锁加锁解锁开销比较小&#xff0c;效率更高重量级锁加锁解锁开销比较大&#xff0c;效率更低多数情况下&#xff0c;乐观锁&#xff0c;也…

在CSDN年收入竟达五位数?----大学生技术自媒体成长之路

前言&#xff1a; Hello大家好&#xff0c;我是Dream。 还有不到两周就要过年了&#xff0c;自己也马上迈入了21岁&#xff0c;感慨时间飞快&#xff0c;从19岁开始入驻C站&#xff0c;到现在也已经整整两年了&#xff0c;把自己最好的两年青春时光留在了CSDN&#xff0c;超百万…

定义输出格式的使用-printf()函数

目录&#x1f4d6;printf()函数简介格式化规定符格式控制特殊规定字符示例printf()函数简介 printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。 printf()函数的调用格式为:printf("<格式化字符串>", <参量表>);这里看输出很简…

Lua入门学习

一、初识Lua脚本 Lua 是一种轻量小巧的脚本语言&#xff0c;用标准C语言编写并以源代码形式开放&#xff0c; 其设计目的是为了嵌入应用程序中&#xff0c;从而为应用程序提供灵活的扩展和定制功能。官网&#xff1a;https://www.lua.org/ 1、HelloWorld CentOS7默认已经安装…

什么是docker

文章目录简介Docker 架构特性局限Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c…