JAVA线程同步通信
以下讲解Lock线程同步通信,也是比synchronized强大的一个功能点
先看一个常规的案例:
用户类
public class Person {
public void eat(){
for(int i=0;i<3;i++){
System.out.println("eat...");
}
}
public void drink(){
for(int i=0;i<3;i++){
System.out.println("drink...");
}
}
public void play(){
for(int i=0;i<3;i++){
System.out.println("play...");
}
}
}
public class LockConditionTest {
public static void main(String[] args) {
final Person person = new Person();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
person.eat();
}
}
}
)
.start();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
person.drink();
}
}
}
)
.start();
for(int i=0;i<10;i++){
person.play();
}
}
}
结果输出:
eat...
eat...
play...
play...
play...
play...
play...
play...
play...
drink...
drink...
play...
play...
play...
play...
以上案例为传统线程调用,打印的结果也是有cpu随机调度输出
现在的需求是:person 吃喝玩方法要有顺序性调用,阻止cpu随机调度输出
参考以下案例(加入Lock实现同步通信):
public class Person {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
private int shouldSub = 1;
public void eat(){
lock.lock();
try{
while(shouldSub!=1){ //是1的时候执行 不是1的时候等待
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<3;i++){
System.out.println("eat...");
}
shouldSub=2;
condition2.signal(); // 1 执行完之后 通知2执行
}finally{
System.out.println("=======================");
lock.unlock();
}
}
public void drink(){
lock.lock();
try{
while(shouldSub!=2){ //是2的时候执行 不是2的时候等待
try {
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<3;i++){
System.out.println("drink...");
}
shouldSub = 3;
condition3.signal();// 2 执行完之后 通知3执行
}finally{
System.out.println("=======================");
lock.unlock();
}
}
public void play(){
lock.lock();
try{
while(shouldSub!=3){ //是3的时候执行 不是3的时候等待
try {
condition3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=0;i<3;i++){
System.out.println("play...");
}
shouldSub = 1;
condition1.signal();// 3 执行完之后 通知1执行
}finally{
System.out.println("=======================");
lock.unlock();
}
}
}
public class LockConditionTest {
public static void main(String[] args) {
final Person person = new Person();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
person.eat();
}
}
}
)
.start();
new Thread(
new Runnable() {
@Override
public void run() {
for(int i=0;i<5;i++){
person.drink();
}
}
}
)
.start();
for(int i=0;i<5;i++){
person.play();
}
}
}
结果输出:
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
JAVA线程同步通信的更多相关文章
- Java线程并发:知识点
Java线程并发:知识点 发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备 ...
- Java线程的概念
1. 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- 细说进程五种状态的生老病死——双胞胎兄弟Java线程
java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
- 第24章 java线程(3)-线程的生命周期
java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- 第22章 java线程(2)-线程同步
java线程(2)-线程同步 本节主要是在前面吃苹果的基础上发现问题,然后提出三种解决方式 1.线程不安全问题 什么叫线程不安全呢 即当多线程并发访问同一个资源对象的时候,可能出现不安全的问题 对于前 ...
- 第21章 java线程(1)-线程初步
java线程(1)-线程初步 1.并行和并发 并行和并发是即相似又有区别: 并行:指两个或者多个事件在同一时刻点发生. 并发:指两个或多个事件在同一时间段内发生 在操作系统中,并发性是指在一段事件内宏 ...
随机推荐
- http请求报文格式(请求行、请求头、空行 和 请求包体)和响应报文格式(状态行、响应头部、空行 和 响应包体)
转载 出处 超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求 ...
- service worker介绍
原文:Service workers explained 译者:neal1991 welcome to star my articles-translator, providing you advan ...
- ll字段 详解 文件权限
文件类型和权限 硬链接总数 属主用户名 属组组名 文件大小(字节) 上次修改时间 文件/目录名 drwxr-xr-x 15 lb lb 4096 10月 19 01:11 ./ drwxr-xr-x ...
- java程序员必知的 8大排序
Java常用的八种排序算法与代码实现 排序问题一直是程序员工作与面试的重点,今天特意整理研究下与大家共勉!这里列出8种常见的经典排序,基本涵盖了所有的排序算法. 1.直接插入排序 我们经常会到这样一类 ...
- maven 自动编译脚本
在maven工程根目录创建windows批处理脚本文件,例如tool.bat,内容如下 @echo off color 1f :menu echo -------------------------- ...
- 【ElicitSearch】启动流程
一.集群启动流程 1.选举主节点 许多节点启动,集群干的第一件事儿就是选主,之后的的流程由主节点触发. 先确定唯一的.大家公认的主节点:再想办法把最新的及其原数据复制到选举的主节点上. 选主是对Bul ...
- c# 生成文件目录树
class Program { //遍历目录名含有M00到M11的目录 //生成文件目录树(去除文件名中含有scc\Designer\designer\resx的文件) //生成的文件保存在D:\\a ...
- php substr()函数 语法
php substr()函数 语法 作用:截取字符串 语法:substr(string,start,length)大理石平台 参数: 参数 描述 string 必需.规定要返回其中一部分的字符串. s ...
- 提示”The following modules are missing or built with a different engine version”
一台机器使用自行编译版本引擎修改了工程后,另一台机器也使用自行编译版本引擎编辑该工程,有时会出现标题的提示 解决办法: 打开\Engine\Binaries\Win64\UE4Editor.modul ...
- vue 3.0 vue-cli项目搭建要点
一.使用vue-cli搭建项目(可使用vue ui图形化界面搭建项目,配置dist时,将名称设为项目名称) 二.项目搭建后 1.配置vue.config.js // 翻阅文档https://cli.v ...