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学习笔记(三)的更多相关文章

  1. JUC学习笔记(六)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...

  2. JUC学习笔记(五)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...

  3. JUC学习笔记(四)

    JUC学习笔记(一)https://www.cnblogs.com/lm66/p/15118407.html JUC学习笔记(二)https://www.cnblogs.com/lm66/p/1511 ...

  4. JUC学习笔记——进程与线程

    JUC学习笔记--进程与线程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的进程与线程部分 我们会分为以下几部分进行介绍: 进程与线程 并发与并行 同步与异步 线程详解 进程与线程 ...

  5. JUC学习笔记——共享模型之管程

    JUC学习笔记--共享模型之管程 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的管程部分 我们会分为以下几部分进行介绍: 共享问题 共享问题解决方案 线程安全分析 Monitor ...

  6. JUC学习笔记——共享模型之内存

    JUC学习笔记--共享模型之内存 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍: Java内存模型 可见性 模式之两阶段终止 模式之Balk ...

  7. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  8. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  9. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

随机推荐

  1. python随机漫步

  2. Unity VideoPlayer视频模糊

    如果视频出现模糊或者尺寸不对只需要修改Texture的Size就可以 注意一点  Size的值要跟视频尺寸一直

  3. Redis的bitmap从基础到业务

    1. 位与字节 1个字节(byte)等于8个位(bit).(计算机常识). 2. string与bitmap Redis里的bitmap是属于string这个数据类型里的.可以help进行查看bit相 ...

  4. Custom Controller CollectionQT样式自定义 001 :SliderLineEdit 滑动输入框

    主要是继承QLineEdit类重新实现其鼠标事件,建议禁用输入框默认的菜单项. SliderLineEdit 滑动输入框 参照图形平台 Adobe系列中属性输入框 做的样式,支持点击编辑和长按鼠标拖动 ...

  5. oracle :如何测试数据库安装是否成功

    要测试数据安装是否成功,可按顺序执行以下两个步骤: 测试步骤 1:  请执行操作系统级的命令: tnsping orcl (如果出现[TNS-03505:无法解析名称]的提示错误: 那就改为tnspi ...

  6. java list 分页

    /** * * @param list * @param pageNum * @param pageSize * @param <T> * @return 返回当前页数据 */ publi ...

  7. keycloak~OIDC&OAuth2&自定义皮肤

    1 OpenID & OAuth2 & SAML 1.1 相关资料 https://github.com/keycloak/keycloak https://www.keycloak. ...

  8. 柔性数组(Redis源码学习)

    柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...

  9. CRM客户管理系统哪个好用

    当企业管理者在进行CRM系统的选型时,面对搜索引擎上五花八门的结果和各式各样的广告,一定会有这样的疑惑:CRM客户管理系统到底哪个好用?抛开网上那些为了广告效果而"夸张"出的优点, ...

  10. Linux使用shell脚本监控

    (1)性能监控脚本 performance.sh #!/bin/bash #-------------------------------------------------------------- ...