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.并行和并发 并行和并发是即相似又有区别: 并行:指两个或者多个事件在同一时刻点发生. 并发:指两个或多个事件在同一时间段内发生 在操作系统中,并发性是指在一段事件内宏 ...
随机推荐
- python学习笔记(8):
一.变量和类型 1.Python基本变量类型: 整数 ,浮点数 ,字符串, 布尔值 ,空值 ,函数, 模块, 类型, 自定义类型 2.变量定义 :变量存储在内存中的值.这就意味着在创建变量时会在内存中 ...
- latex中\large的作用域问题
在毕业论文的写作过程中,遇到了一个\large 作用域的问题.假设下面有三种写法: I am cool \large{you are right}, yeah, yeah, yeah I am coo ...
- runtime 理解笔记
runtime 简称运行时,是系统运行的一种机制,在oc中通过c语言编写一个运行系统库.考进行一些非常底层的操作(oc无法完成的). 1.利用runtime,在程序运行过程中,动态创建一个类(比如KV ...
- ElasticSearch基本概念阐述
下面阐述一下ES当中的一些常见词语含义: 集群 集群由一个或多个节点组成,对外提供服务,索引和搜索功能.在所有的节点中,一个集群有一个唯一的名称默认为“ElasticSearch”,此名称很重要,因为 ...
- 02.Linux-CentOS系统Firewalld防火墙配置
1.firewalld的基本使用 启动: systemctl start firewalld关闭: systemctl stop firewalld查看状态: systemctl status fir ...
- Linux性能优化从入门到实战:03 CPU篇:CPU上下文切换
linux操作系统是将CPU轮流分配给任务,分时执行的.而每次执行任务时,CPU需要知道CPU寄存器(CPU内置的内存)和程序计数器PC(CPU正在执行指令和下一条指令的位置)值,这些值是CPU执 ...
- javascript笔记收集
因为前端编程的兴起, 慢慢地对css/javascript越来越淡, 偶尔用一下,得查半天资料. 这里就收藏一下比较生僻, 但是做工具时会用到的. json获取属性名 Object.keys(), 只 ...
- Centos抓包方法
1. 安装tcpdump工具 rpm -ql tcpdump #查看tcpdump是否安装 本机是安装的,yum安装: yum install tcpdump 2. tcpdump抓包 根据协议和端 ...
- Delphi 清理程序内存
procedure ClearMemory;begin if Win32Platform = VER_PLATFORM_WIN32_NT then begin ...
- 【SpringBoot】 项目中运用的一些技巧,mybatis-plus 自动编译等(持续更新)
前言 本文将总结项目中用到的一些springboot 的技巧,持续更新. Mybatis-Plus 的运用 使用原因: 主要是节省了Mapper层的编写,通过继承BaseMapper可以直接调用通用的 ...