当前位置: 首页 > news >正文

[one_demo_17]使用传统方式实现线程间通信的例子

题目: 子线程循环10次,接着到主线程循环10次;接着又回到子线程循环10次,接着又到主线程循环10次,如此循环50次。

使用Object的wait()和notify()方法实现。

Java代码

第一种,不使用面向对象的思想实现

/**
 * 练习线程间通信
 * 
 * @author Administrator
 *
 */
public class ThreadCommunicationOld {
	// 锁
	private static String lock = "lock";

	// 线程间通信的开关
	private static boolean isSub = true;

	public static void main(String[] args) {

		// 子线程
		new Thread(new Runnable() {
			public void run() {
				// 循环50次
				for (int i = 0; i < 50; i++) {
					// 加锁
					synchronized (lock) {
						// 如果不是子线程状态,就让子线程阻塞
						if (!isSub) {
							try {
								lock.wait();
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
						}
						// 执行任务10次
						for (int j = 0; j < 10; j++) {
							System.out.println("sub thread sequence of " + j + ", loop of " + i);
						}
						// 执行完任务后,调整为非子线程状态
						isSub = false;
						// 唤醒主线程
						lock.notify();
					}
				}
			}
		}).start();

		// 主线程,执行50次
		for (int i = 0; i < 50; i++) {
			// 主线程加锁
			synchronized (lock) {
				// 判断是否为子线程状态,如果是子线程状态,就让主线程阻塞
				if (isSub) {
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				// 执行任务10次
				for (int j = 0; j < 10; j++) {
					System.out.println("main thread sequence of " + j + ", loop of " + i);
				}
				// 调整为子线程状态
				isSub = true;
				// 唤醒子线程
				lock.notify();
			}
		}
	}

}

第二种,使用面向对象的思想,将执行的业务放在一个业务类中,在这个业务类中,将执行的方法加上同步;另外,在判断线程状态时使用while取代if,防止出现假唤醒,也就是每次拿到锁后,都要判断状态。

/**
 * 练习线程间通信 题目: 子线程循环10次,接着到主线程循环100次;接着又回到子线程循环10次,接着又到主线程循环100次,如此循环50次
 * 
 * @author Administrator
 *
 */
public class ThreadCommunicationOld2 {

	public static void main(String[] args) {
		// 创建业务对象
		final Business business = new Business();
		// 子线程
		new Thread(new Runnable() {
			public void run() {
				// 循环50次
				for (int i = 0; i < 50; i++) {
					// 子线程业务
					business.sub(i);
				}
			}
		}).start();

		// 主线程,执行50次
		for (int i = 0; i < 50; i++) {
			// 主线程业务
			business.main(i);
		}

	}
}

// 将主线程或者子线程的业务交给业务类管理,更加的面向对象
class Business {
	// 线程状态标识
	private boolean isSub = true;

	// 主线程业务
	public synchronized void main(int i) {
		// 判断是否为子线程状态,如果是子线程状态,就让主线程阻塞
		while (isSub) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 执行任务10次
		for (int j = 0; j < 10; j++) {
			System.out.println("main thread sequence of " + j + ", loop of " + i);
		}
		// 调整为子线程状态
		isSub = true;
		// 唤醒子线程
		this.notify();
	}

	// 子线程业务
	public synchronized void sub(int i) {
		// 如果不是子线程状态,就让子线程阻塞
		while (!isSub) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		// 执行任务10次
		for (int j = 0; j < 10; j++) {
			System.out.println("sub thread sequence of " + j + ", loop of " + i);
		}
		// 执行完任务后,调整为非子线程状态
		isSub = false;
		// 唤醒主线程
		this.notify();
	}
}

 

相关文章:

  • ThreadLocal
  • [one_demo_18]js定时器的示例
  • Java8部分新特性
  • jvm简介
  • mybatis使用foreach处理List中的Map
  • log4j2的配置文件
  • 一个用java的NIO实现的socket的客户端和服务端的demo
  • 使用java的nio的pipe实现两个线程间传送数据的demo
  • org.hibernate.TransactionException: nested transactions not supported异常
  • elasticsearch
  • rancher简介
  • InfluxDB+cAdvisor+Grafana容器管理
  • serviceComb[No schema defined for start.servicecomb.io:]异常
  • ServiceComb
  • kubernetes
  • 2019.2.20 c++ 知识梳理
  • AWS实战 - 利用IAM对S3做访问控制
  • canvas 绘制双线技巧
  • es6
  • HTML中设置input等文本框为不可操作
  • Java程序员幽默爆笑锦集
  • Koa2 之文件上传下载
  • Linux中的硬链接与软链接
  • MD5加密原理解析及OC版原理实现
  • mongodb--安装和初步使用教程
  • Object.assign方法不能实现深复制
  • Odoo domain写法及运用
  • Rancher如何对接Ceph-RBD块存储
  • Redis字符串类型内部编码剖析
  • Spark学习笔记之相关记录
  • SpringBoot 实战 (三) | 配置文件详解
  • 分布式熔断降级平台aegis
  • 基于组件的设计工作流与界面抽象
  • 记一次删除Git记录中的大文件的过程
  • 记一次用 NodeJs 实现模拟登录的思路
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 学习笔记TF060:图像语音结合,看图说话
  • 用简单代码看卷积组块发展
  • 怎么把视频里的音乐提取出来
  • 仓管云——企业云erp功能有哪些?
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 正则表达式-基础知识Review
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (补)B+树一些思想
  • (转)树状数组
  • (转)一些感悟
  • .NET CORE Aws S3 使用
  • .net 流——流的类型体系简单介绍
  • .net 怎么循环得到数组里的值_关于js数组
  • .Net 知识杂记
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .net对接阿里云CSB服务
  • ??如何把JavaScript脚本中的参数传到java代码段中