JUC学习笔记(三)
JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html
JUC学习笔记(二)https://www.cnblogs.com/lm66/p/15118813.html
1、线程间通信
线程间通信的模型有两种:共享内存和消息传递,以下方式都是基本这两种模型来实现的。我们来基本一道面试常见的题目来分析
场景---两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1,要求用线程间通信
1.1、synchronized 方案
public class ThreadDemo1 {
public static void main(String[] args) {
Share share = new Share();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "BB").start();
}
}
class Share {
private int num = 0;
public synchronized void increment() throws Exception {
while (num != 0) {
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName() + "::" + num);
this.notifyAll();
}
public synchronized void decrement() throws Exception {
while (num != 1) {
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName() + "::" + num);
this.notifyAll();
}
}
1.2、Lock方案
public class ThreadDemo2 {
public static void main(String[] args) {
Share2 share = new Share2();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "AA").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
share.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
}, "BB").start();
}
}
class Share2 {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private int num = 0;
public void increment() throws Exception {
lock.lock();
try {
while (num != 0) {
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName() + "::" + num);
condition.signalAll();
} finally {
lock.unlock();
}
}
public void decrement() throws Exception {
lock.lock();
try {
while (num != 1) {
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName() + "::" + num);
condition.signalAll();
} finally {
lock.unlock();
}
}
}
1.3、线程间定制化通信
1.3.1、案例介绍
问题: A 线程打印 5 次 A,B 线程打印 10 次 B,C 线程打印 15 次 C,按照此顺序循环 10 轮
1.3.2、实现流程
public class ThreadDemo3 {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print5(i);
} catch (Exception e) {
}
}
},"AA").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print10(i);
} catch (Exception e) {
}
}
},"BB").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
shareResource.print15(i);
} catch (Exception e) {
}
}
},"CC").start();
}
}
class ShareResource {
// 定义标志位
private int flag = 1;
// 创建Lock锁
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(int loop) throws Exception {
lock.lock();
try {
// 判断。防止虚假唤醒
while (flag != 1) {
// 等待
c1.await();
}
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "::" + loop);
}
// 修改标志位
flag = 2;
// 通知
c2.signal();
} finally {
lock.unlock();
}
}
public void print10(int loop) throws Exception {
lock.lock();
try {
while (flag != 2) {
c2.await();
}
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "::" + loop);
}
flag = 3;
c3.signal();
} finally {
lock.unlock();
}
}
public void print15(int loop) throws Exception {
lock.lock();
try {
while (flag != 3) {
c3.await();
}
for (int i = 0; i < 15; i++) {
System.out.println(Thread.currentThread().getName() + "::" + loop);
}
flag = 1;
c1.signal();
} finally {
lock.unlock();
}
}
}

JUC学习笔记(三)的更多相关文章
- JUC学习笔记(六)
JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...
- JUC学习笔记(五)
JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...
- JUC学习笔记(四)
JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...
- JUC学习笔记——进程与线程
JUC学习笔记--进程与线程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的进程与线程部分 我们会分为以下几部分进行介绍: 进程与线程 并发与并行 同步与异步 线程详解 进程与线程 ...
- JUC学习笔记——共享模型之管程
JUC学习笔记--共享模型之管程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的管程部分 我们会分为以下几部分进行介绍: 共享问题 共享问题解决方案 线程安全分析 Monitor ...
- JUC学习笔记——共享模型之内存
JUC学习笔记--共享模型之内存 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍: Java内存模型 可见性 模式之两阶段终止 模式之Balk ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
随机推荐
- 快速简单的了解VLAN(VXLAN)和端口链路类型
目录 前言 一.VLAN是什么? 1.优点 2.为什么推出VXLAN 二.VXLAN又是什么? 1.优点 三.创建VLAN 四.介绍端口链路类型 五.Access 1.特性 六.Trunk 1.特性 ...
- 【NLP学习其三】在学习什么是嵌入之前,你应该了解什么是词语表征
在了解什么是嵌入(embeddings)之前,我们需要先搞清楚一个词语在NLP中是如何被表示的 注:本次不涉及任何具体算法,只是单纯对概念的理解 词汇表征 One-Hot 词汇的表示方法有很多,最有名 ...
- CentOS7详细安装教程(图文)
CentOS7安装过程:(图文详解) 为了做实验,装台Linux的虚拟机,手上有这个7的ISO文件就懒得去下载8的了. 0X01.虚拟机配置 0X02.CentOS7系统配置安装 分别创建/boot区 ...
- POJ 3087 Shuffle'm Up 模拟,看着不像搜索啊
题意:给定s1,s1两副扑克,顺序从下到上.依次将s2,s1的扑克一张一张混合.例如s1,ABC; s2,DEF. 则第一次混合后为DAEBFC. 然后令前半段为s1, 后半段为s2. 如果可以变换成 ...
- Java实验项目二——小学生考试系统(简单四则运算)
Program:设计实现一个小学生数学考试系统,完成随机出题(简单的四则运算),学生答题,自动判分的功能. Description:代码如下: 1 /* 2 * Description:面向考试系统建 ...
- ZSH主题
All the current themes can be found in the themes/ directory in the oh-my-zsh distribution. See list ...
- VS2017 常用快捷键
项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt + L = 显示 Solution Explorer(解决方案资源管理器) Shift + Alt+ C = 添 ...
- Python单元测试框架unittest之生成测试报告(HTMLTestRunner)
前言 批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的. unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLT ...
- mysql 修改my.ini
1.C:\Program Files\MySQL\MySQL Server 5.5\bin>mysqladmin shutdown可能提示:localhost不能启动mysql2.C:\Prog ...
- Java基础00-网络编程29
1. 网络编程入门 1.1 网络编程概述 1.2 网络编程三要素 1.3 IP地址 在命令提示符中使用 1.4 InetAddress的使用 代码示例: public class InetAddres ...