JUC-线程间通信
面试题:
两个线程,一个线程打印1-52,另一个打印字母A-Z打印顺序为12A34B...5152Z,
要求用线程间通信
线程间通信:1、生产者+消费者2、通知等待唤醒机制
多线程编程模版中
1、判断
2、干活
3、唤醒
synchronized实现
- package com.atguigu.thread;
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- import org.omg.IOP.Codec;
- class ShareDataOne//资源类
- {
- private int number = 0;//初始值为零的一个变量
- public synchronized void increment() throws InterruptedException
- {
- //1判断
- if(number !=0 ) {
- this.wait();
- }
- //2干活
- ++number;
- System.out.println(Thread.currentThread().getName()+"\t"+number);
- //3通知
- this.notifyAll();
- }
- public synchronized void decrement() throws InterruptedException
- {
- // 1判断
- if (number == 0) {
- this.wait();
- }
- // 2干活
- --number;
- System.out.println(Thread.currentThread().getName() + "\t" + number);
- // 3通知
- this.notifyAll();
- }
- }
- /**
- *
- * @Description:
- *现在两个线程,
- * 可以操作初始值为零的一个变量,
- * 实现一个线程对该变量加1,一个线程对该变量减1,
- * 交替,来10轮。
- * @author xialei
- *
- * * 笔记:Java里面如何进行工程级别的多线程编写
- * 1 多线程变成模板(套路)-----上
- * 1.1 线程 操作 资源类
- * 1.2 高内聚 低耦合
- * 2 多线程变成模板(套路)-----下
- * 2.1 判断
- * 2.2 干活
- * 2.3 通知
- */
- public class NotifyWaitDemoOne
- {
- public static void main(String[] args)
- {
- ShareDataOne sd = new ShareDataOne();
- new Thread(() -> {
- for (int i = 1; i < 10; i++) {
- try {
- sd.increment();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "A").start();
- new Thread(() -> {
- for (int i = 1; i < 10; i++) {
- try {
- sd.decrement();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }, "B").start();
- }
- }
- /*
- * *
- * 2 多线程变成模板(套路)-----下
- * 2.1 判断
- * 2.2 干活
- * 2.3 通知
- * 3 防止虚假唤醒用while
- *
- *
- * */
换成4个线程会导致错误,虚假唤醒
原因:在java多线程判断时,不能用if,程序出事出在了判断上面,
突然有一添加的线程进到if了,突然中断了交出控制权,
没有进行验证,而是直接走下去了,加了两次,甚至多次
解决虚假唤醒:查看API,java.lang.Object
中断和虚假唤醒是可能产生的,所以要用loop循环,if只判断一次,while是只要唤醒就要拉回来再判断一次。if换成while
java8实现
- Condition:查看API,java.util.concurrent
- 
- class BoundedBuffer {
- final Lock lock = new ReentrantLock();
- final Condition notFull = lock.newCondition();
- final Condition notEmpty = lock.newCondition();
- final Object[] items = new Object[100];
- int putptr, takeptr, count;
- public void put(Object x) throws InterruptedException {
- lock.lock();
- try {
- while (count == items.length)
- notFull.await();
- items[putptr] = x;
- if (++putptr == items.length) putptr = 0;
- ++count;
- notEmpty.signal();
- } finally {
- lock.unlock();
- }
- }
线程间定制化调用通信
- package com.atguigu.thread;
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- class ShareResource
- {
- private int number = 1;//1:A 2:B 3:C
- private Lock lock = new ReentrantLock();
- private Condition c1 = lock.newCondition();
- private Condition c2 = lock.newCondition();
- private Condition c3 = lock.newCondition();
- public void print5(int totalLoopNumber)
- {
- lock.lock();
- try
- {
- //1 判断
- while(number != 1)
- {
- //A 就要停止
- c1.await();
- }
- //2 干活
- for (int i = 1; i <=5; i++)
- {
- System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber);
- }
- //3 通知
- number = 2;
- c2.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void print10(int totalLoopNumber)
- {
- lock.lock();
- try
- {
- //1 判断
- while(number != 2)
- {
- //A 就要停止
- c2.await();
- }
- //2 干活
- for (int i = 1; i <=10; i++)
- {
- System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber);
- }
- //3 通知
- number = 3;
- c3.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- public void print15(int totalLoopNumber)
- {
- lock.lock();
- try
- {
- //1 判断
- while(number != 3)
- {
- //A 就要停止
- c3.await();
- }
- //2 干活
- for (int i = 1; i <=15; i++)
- {
- System.out.println(Thread.currentThread().getName()+"\t"+i+"\t totalLoopNumber: "+totalLoopNumber);
- }
- //3 通知
- number = 1;
- c1.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
- }
- }
- /**
- *
- * @Description:
- * 多线程之间按顺序调用,实现A->B->C
- * 三个线程启动,要求如下:
- *
- * AA打印5次,BB打印10次,CC打印15次
- * 接着
- * AA打印5次,BB打印10次,CC打印15次
- * ......来10轮
- * @author xialei
- *
- */
- public class ThreadOrderAccess
- {
- public static void main(String[] args)
- {
- ShareResource sr = new ShareResource();
- new Thread(() -> {
- for (int i = 1; i <=10; i++)
- {
- sr.print5(i);
- }
- }, "AA").start();
- new Thread(() -> {
- for (int i = 1; i <=10; i++)
- {
- sr.print10(i);
- }
- }, "BB").start();
- new Thread(() -> {
- for (int i = 1; i <=10; i++)
- {
- sr.print15(i);
- }
- }, "CC").start();
- }
- }
JUC-线程间通信的更多相关文章
- juc包:使用 juc 包下的显式 Lock 实现线程间通信
一.前置知识 线程间通信三要素: 多线程+判断+操作+通知+资源类. 上面的五个要素,其他三个要素就是普通的多线程程序问题,那么通信就需要线程间的互相通知,往往伴随着何时通信的判断逻辑. 在 java ...
- 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 { // 创建两 ...
- Java笔记(二十)……线程间通信
概述 当需要多线程配合完成一项任务时,往往需要用到线程间通信,以确保任务的稳步快速运行 相关语句 wait():挂起线程,释放锁,相当于自动放弃了执行权限 notify():唤醒wait等待队列里的第 ...
随机推荐
- python部署到服务器
python部署到服务器 linux下的CentOS 7 自带python2.7.5, 使用 python --version 命令查看,因系统需要python2.7.5,因此我们并不卸载,另外安装p ...
- cf912D
题意简述:往n*m的网格中放k条鱼,一个网格最多放一条鱼,然后用一个r*r的网随机去捞鱼,问怎么怎么放鱼能使得捞鱼的期望最大,输出这个期望 题解:肯定优先往中间放,这里k不大,因此有别的简单方法,否则 ...
- Qt代码区字符编码转换
在做通讯练习的时候,发现发送给小助手字符乱码,图片如下 本人Qt Creator是UTF-8,需要改成gbk,代码如下 #include<QTextCodec> // 提供字符编码转换 Q ...
- 等差数列,for循环,递归和尾递归的对比
生活中,如果1+2+3+4.....+100,大家基本上都会用等差数列计算,如果有人从1开始加,不是傻就是白X,那么程序中呢,是不是也是这样.今天无意中看到了尾递归,以前也写过,但是不知道这个专业名词 ...
- centos7 lnmp环境搭建
1- 安装gcc c++编译器 yum install gcc gcc-c++ cmake 2- 安装nginx-1.8.1及依赖包 2.1- 安装nginx依赖包 yum -y install pc ...
- P1308 统计单词数(cin,getline() ,transform() )
题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...
- 解决const char* to char* 的错误
一般情况下 char* string = "abc"; 编译后会出现标题中的错误. 我们只需要在字符串前加上const_cast<char*>即可,这个作用是丢弃变量的 ...
- github访问过慢
转:https://baijiahao.baidu.com/s?id=1608100091125662190&wfr=spider&for=pc https://www.cnblogs ...
- Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
课程目标掌握如何基于Spring Boot构建秒杀系统或者高并发业务系统,以及构建系统时采用的前后端技术栈适用人群Spring Boot实战者,微服务或分布式系统架构实战者,秒杀系统和高并发实战者,中 ...
- 获取WEB图片
public string GetJpgFile(string strFileServerPath ,string strReportDir) { string strPath = "&qu ...