一、普通的线程间通信

  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. 关于kafka中consumer subscribe与asssign的理解

    kafka中consumer subscribe与asssign的理解: https://blog.csdn.net/weixin_34332905/article/details/91392030

  2. brew清华镜像

    https://mirror.tuna.tsinghua.edu.cn/help/homebrew/

  3. vsCode 搭建Java开发环境

    1.安装扩展 Java Extension Pack Spring Boot Extension Pack 2.配置Maven 打开设置 搜索maven 找到并打开  在 settings.json ...

  4. Python-在不在判断 in 和 in判断协议- in __contains__

    in 判断元素是否在序列中, 可以查看 in == is 区别 __contians__ 如果是对象则调用对象中的 __contains__方法 class BeiMenChuiXue: def __ ...

  5. Centos-bash-4.1$

    错误: -bash-4.1$ where? 登录Centos时候,会显示4行这样的错误信息-bash-4.1$ why? 1. 该用户家目录缺少 .bashrc .bash_logout .base_ ...

  6. Centos-强制将内存中数据写入磁盘-sync

    sync 强制将内存中数据写入磁盘,以免数据丢失.在linux系统中,修改过的操作并不会立即写入磁盘,而是先写到内存中,通过buffer队列当达到指定时间或者指定大小再一次性写入磁盘,提高IO效率,正 ...

  7. C++ | 继承(基类,父类,超类),(派生类,子类)

    转载:https://blog.csdn.net/Sherlock_Homles/article/details/82927515 文章参考:https://blog.csdn.net/war1111 ...

  8. c++中CString:: Find , ReverseFind, Left, Right

    CString 是在MFC中的头文件 非MFC加上afx.h头文件 直接上代码: // ConsoleApplication1.cpp : Defines the entry point for th ...

  9. matlab做gaussian高斯滤波

    原文链接:https://blog.csdn.net/humanking7/article/details/46826105 核心提示 在Matlab中高斯滤波非常方便,主要涉及到下面两个函数: 函数 ...

  10. HTML & CSS & JavaScript 从一个表格到一个灰阶颜色表 04

    工具1:HBuilder X 1.9.9.20190522 工具2:火狐浏览器 67.0.4 (64 位) 目前,我们已经将一些行和列插入到表格中,并设置单元格的背景颜色,显示 RGB 值等. 例 7 ...