JUC---05线程间通信(一)
一、普通的线程间通信
1.synchronized实现
package com.jenne.mydemo; class ShareDataOne { private int number = 0; public synchronized void incr() {
try {
//判断
while (number != 0) {
wait();
}
//干活
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number); //通知
notifyAll();
} catch (Exception e) {
e.printStackTrace();
} } public synchronized void decr() {
try {
//判断
while (number != 1) {
wait();
}
//干活
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number); //通知
notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
} public class NotifyWaitDemo { public static void main(String[] args) {
ShareDataOne shareDataOne = new ShareDataOne();
//++
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareDataOne.incr();
}
}, "AA").start(); //--
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareDataOne.decr();
}
}, "BB").start(); //++
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareDataOne.incr();
}
}, "CC").start(); //--
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
shareDataOne.decr();
}
}, "DD").start(); } }
2.Lock锁实现
package com.jenne.mydemo; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; class ShareDataOne { private int number = 0; private Lock lock = new ReentrantLock();//创建可重用锁
private Condition cd = lock.newCondition();//替换Object监测方法( wait, notify和 notifyAll)等 public void incr() throws InterruptedException {
lock.lock();
try {
//判断
while (number != 0) {
cd.await();
}
//干活
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number); //通知
cd.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
} } public void decr() throws InterruptedException {
lock.lock();
try {
//判断
while (number != 1) {
cd.await();
}
//干活
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number); //通知
cd.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
} public class NotifyWaitDemo { public static void main(String[] args) {
ShareDataOne shareDataOne = new ShareDataOne(); //++
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
try {
shareDataOne.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "AA").start(); //--
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
try {
shareDataOne.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "BB").start(); //++
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
try {
shareDataOne.incr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "CC").start(); //--
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
try {
shareDataOne.decr();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "DD").start(); } }
3.注意:
在上面两种实现简单的线程通信时,判断是否操作都是用while循环。为什么我们不用if判断呢?使用if会造成虚假唤醒操作。在java多线程判断时,不能用if,程序出事出在了判断上面,突然有一添加的线程进到if了,突然中断了交出控制权,没有进行验证,而是直接走下去了,加了两次,甚至多次
JUC---05线程间通信(一)的更多相关文章
- juc包:使用 juc 包下的显式 Lock 实现线程间通信
一.前置知识 线程间通信三要素: 多线程+判断+操作+通知+资源类. 上面的五个要素,其他三个要素就是普通的多线程程序问题,那么通信就需要线程间的互相通知,往往伴随着何时通信的判断逻辑. 在 java ...
- JUC之线程间的通信
线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- 线程间通信 GET POST
线程间通信有三种方法:NSThread GCD NSOperation 进程:操作系统里面每一个app就是一个进程. 一个进程里面可以包含多个线程,并且我们每一个app里面有且仅有一 ...
- Java多线程编程核心技术---线程间通信(二)
通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...
- Java多线程编程核心技术---线程间通信(一)
线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一.线程间通信可以使系统之间的交互性更强大,在大大提高CPU利用率的同时还会使程序员对各 ...
- volatile关键字与线程间通信
>>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...
- 06_Java多线程、线程间通信
1. 线程的概念 1.1多进程与多线程 进程:一个正在执行的程序.每个进程执行都有一个执行顺序,该顺序是一个执行路径,或叫一个控制单元. 一个进程至少有一个线程. 线程:就是进程中的一个独立 ...
- 【原】iOS多线程之线程间通信和线程互斥
线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...
- java多线程系列5-死锁与线程间通信
这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两 ...
随机推荐
- Centos7防火墙以及端口控制
开启防火墙 systemctl start firewalld.service --启动firewall systemctl enable firewalld.service --开机时启动firew ...
- MMC & SD 发展历史
一.概述 MMC 卡和 SD 卡都是基于 Nand Flash 技术的移动存储卡. MMC(MultiMediaCard) 卡于 1997 年由西门子和 Sandisk 推出,SD (Secure D ...
- 概率派VS贝叶斯派
机器学习中的MLE和MAP两大学派的争论: 频率学派 - Frequentist - Maximum Likelihood Estimation (MLE,最大似然估计): 频率学派认为世界是确定的, ...
- 可变参数__VA_ARGS__使用
1. 调试功能一般会使用到宏+可变参数的方式 1.1 ##__VA_ARGS__ 之详细解析 例如: case A. #define my_print1(...) printf(__V ...
- MATLAB中exist函数的用法
exist:exist主要有两种形式,一个参数和两个参数的,作用都是用于确定某值是否存在:1. b = exist( a) 若 a 存在,则 b = 1: 否则 b = 0:2. b = e ...
- 利用 JS 脚本实现网页全自动秒杀抢购
利用 JS 脚本实现网页全自动秒杀抢购 倒计时页面: 倒计时未结束时,购买按钮还不能点击. 结束时,可以点击购买,点击后出现提示"付款成功" 展示效果 1.制作测试网页 首先我们来 ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- 使用phpword获取doc中的表格数据
1. 首先确定使用phpword是可以读取word文档中表格里面的数据, 使用的phpword版本0.17.0 2.理解word文档内容的存储逻辑规则(这里只做简单概述) 一般做博文喜欢直接贴代码,直 ...
- DX12龙书 02 - DirectXMath 库中与向量有关的类和函数
0x00 需要用到的头文件 #include <DirectXMath> #include <DirectXPackedVector.h> using namespace Di ...
- web中的HTML CSS
HTML 超文本标记语言 页面的结构 首行声明文档类型>根标记>头部标记/主体标记 标记 div 布局 切割 分割 划分区域 spa ...