一、普通的线程间通信

  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线程间通信(一)的更多相关文章

  1. juc包:使用 juc 包下的显式 Lock 实现线程间通信

    一.前置知识 线程间通信三要素: 多线程+判断+操作+通知+资源类. 上面的五个要素,其他三个要素就是普通的多线程程序问题,那么通信就需要线程间的互相通知,往往伴随着何时通信的判断逻辑. 在 java ...

  2. JUC之线程间的通信

    线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...

  3. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  4. 线程间通信 GET POST

    线程间通信有三种方法:NSThread   GCD  NSOperation       进程:操作系统里面每一个app就是一个进程. 一个进程里面可以包含多个线程,并且我们每一个app里面有且仅有一 ...

  5. Java多线程编程核心技术---线程间通信(二)

    通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...

  6. Java多线程编程核心技术---线程间通信(一)

    线程是操作系统中独立的个体,但这些个体如果不经过特殊处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一.线程间通信可以使系统之间的交互性更强大,在大大提高CPU利用率的同时还会使程序员对各 ...

  7. volatile关键字与线程间通信

    >>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...

  8. 06_Java多线程、线程间通信

    1. 线程的概念      1.1多进程与多线程 进程:一个正在执行的程序.每个进程执行都有一个执行顺序,该顺序是一个执行路径,或叫一个控制单元. 一个进程至少有一个线程. 线程:就是进程中的一个独立 ...

  9. 【原】iOS多线程之线程间通信和线程互斥

    线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...

  10. java多线程系列5-死锁与线程间通信

    这篇文章介绍java死锁机制和线程间通信 死锁 死锁:两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象. 同步代码块的嵌套案例 public class MyLock { // 创建两 ...

随机推荐

  1. JVM学习(二)JVM加载类

    一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  2. 解决flutter 运行时:Waiting for another flutter command to release the startup lock...

    执行 Flutter 包管理相关命令时有可能遇到 Waiting for another flutter command to release the startup lock... 这样的错误,可尝 ...

  3. Processing 网格(棋盘格)无限偏移纹理动画

    过火 再度出击!这次我们要玩得更火一点---把静帧变动画.没错,将棋盘格动起来!看一下效果: 这是一个经典的无限偏移动画,在很多2d横版射击游戏中都会采用的技术.如何在Processing中实现,有两 ...

  4. springboot项目整合rabbitMq涉及消息的发送确认,消息的消费确认机制,延时队列的实现

    1.引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactI ...

  5. git push 提交时出错 the remote end hung up unexpectedly

    错误原因 与远程服务的连接中断,但是检查发现origin还在,可能是文件太大,缓存不够,增加缓存大小 解决方案 专案目录 >.git >config 在末尾增加如下代码 [http] po ...

  6. How to read h5 file by Matlab

    In matlab, one can use the following command to read h5 file data = h5read(filename,ds) data = h5rea ...

  7. 编程体系结构(05):Java多线程并发

    本文源码:GitHub·点这里 || GitEE·点这里 一.多线程导图 二.多线程基础 1.基础概念 线程是操作系统能够进行运算调度的最小单位,包含在进程之中,是进程中的实际运作单位.一条线程指的是 ...

  8. Spring Boot 第六弹,拦截器如何配置,看这儿~

    持续原创输出,点击上方蓝字关注我吧 目录 前言 Spring Boot 版本 什么是拦截器? 如何自定义一个拦截器? 如何使其在Spring Boot中生效? 举个栗子 思路 根据什么判断这个接口已经 ...

  9. 题解 CF149D

    题目链接 首先,这是一道区间dp题: 首先我们假设 \(l\) ~ \(r\) 是一段合法的区间: 考虑状态,对于一个区间 \(l\) ~ \(r\) 的方案数,我们需要知道方案数,以及 \(l ,r ...

  10. 正则表达式查找“不包含XXX字符串”

    使用 当我要找到不包含某些字符串(如test)时, 可以使用 # 独立使用 (?!test). # 加头尾判断 ^((?!test).)*$ 原理 正则表达式的断言功能: (?=pattern) 非获 ...