Java高并发程序设计(三)——JDK并发包(二)
引言
好久没来学习Java高并发程序设计了,感觉在慢慢遗忘之前学过的内容,今天打算重新拾起。
Condition
Condition与前两章讲的Object.wait() 和Object.notify()是很像的,基本的语法如下:
- await() 方法会使当前的线程等待,同时释放当前锁,当其他线程使用signal或者signalall方法时,当前线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待。
- awaitUninterruptibly方法与await方法基本相同,但是他并不会在等待过程中响应中断。
来看具体示例:
package JAVA高并发程序设计.JDK并发包;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;/*** Author:haozhixin* Func: condition条件* Date: 20190824*/
public class ReenterLockCondition implements Runnable {public static ReentrantLock reentrantLock = new ReentrantLock();public static Condition condition=reentrantLock.newCondition();@Overridepublic void run() {try {reentrantLock.lock();condition.await();System.out.println("Thread is going on");}catch (InterruptedException e){e.printStackTrace();}finally {reentrantLock.unlock();}}public static void main(String []args) throws InterruptedException{ReenterLockCondition reentrantLock1 = new ReenterLockCondition();Thread tl = new Thread(reentrantLock1);tl.start();Thread.sleep(2000);//通知线程tl继续执行reentrantLock.lock();//必须先获得锁condition.signal();//启用通知reentrantLock.unlock();//必须释放锁}
}
信号量(Semaphore)
- Semaphore是一个计数信号量,它的本质是一个"共享锁"。 信号量为多线程的协作提供了更为强大的控制方法,广义上说,信号量是对锁的拓展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问一个资源,而信号量却可以指定多个线程,同时访问某一个资源。
- 信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。
package JAVA高并发程序设计.JDK并发包;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;/*** Author:haozhixin* Func: 信号量的使用* Date: 20190824*/
public class SempleDemo implements Runnable{final Semaphore semaphore = new Semaphore(5);//非公平共享锁,申请了5个许可,并且防止变化定义为final@Overridepublic void run() {try {semaphore.acquire();//信号启动Thread.sleep(2000);System.out.print(Thread.currentThread().getId() + ":done!");semaphore.release();//信号量结束}catch (InterruptedException e){e.printStackTrace();}}public static void main(String [] args){ExecutorService executorService = Executors.newFixedThreadPool(20);final SempleDemo sempleDemo = new SempleDemo();for(int i=0;i<20;i++){executorService.submit(sempleDemo);}}
}
读写锁
读写锁可以有效的帮助减少锁竞争,提升系统性能。用锁分离的机制来提升性能非常容易理解,比如线程A1,A2,A3进行写操作,B1,B2,B3进行读操作,如果使用重入锁或者内部锁,则理论上所有操作,无论哪种组合都是串行操作。当B1读取时,B2,B3则需要等待锁。由于读操作并不对数据的完整性造成破坏,这种等待显然是不合理的。读写锁的约束可以描述如下:
- 读-读不互斥:读与读之间互不阻塞。
- 读-写互斥:读阻塞写,写也阻塞读。
- 写-写互斥:写写阻塞。
一般来说,读的操作次数远大于写操作,则读写锁可以发挥更大的功效。看一下应用案例:
package JAVA高并发程序设计.JDK并发包;import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;/*** Author:haozhixin* Func: 读写锁场景模拟* Date: 20190824*/
public class ReadWriteLockDemo {private static Lock lock = new ReentrantLock();private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();private static Lock readLock = reentrantReadWriteLock.readLock();private static Lock writeLock = reentrantReadWriteLock.writeLock();private int value;public Object handleRead(Lock lock) throws InterruptedException{try {lock.lock();Thread.sleep(1000);return value;}finally {lock.unlock();}}public void handleWrite(Lock lock,int index) throws InterruptedException{try {lock.lock();Thread.sleep(1000);value=index;}finally {lock.unlock();}}public static void main(String[]args){final ReadWriteLockDemo demo = new ReadWriteLockDemo();Runnable readRunnable = new Runnable() {@Overridepublic void run() {try{demo.handleRead(readLock);//demo.handleRead(lock);}catch (InterruptedException e){e.printStackTrace();}}};Runnable writeRunnable = new Runnable() {@Overridepublic void run() {try{demo.handleWrite(writeLock,new Random().nextInt());//demo.handleWrite(lock,new Random().nextInt());}catch (InterruptedException e){e.printStackTrace();}}};for(int i=0;i<20;i++){new Thread(readRunnable).start();}for(int i=0;i<2;i++){new Thread(writeRunnable).start();}}
}
在读操作十分耗时的时候,尽量使用读写锁分离,防止因读阻塞写入数据库。下一章我们介绍下线程池。
作者:select you from me
来源:CSDN
转载请联系作者获得授权并注明出处。
Java高并发程序设计(三)——JDK并发包(二)相关推荐
- 《实战 Java 高并发程序设计》笔记——第3章 JDK 并发包(二)
文章目录 3.2 线程复用:线程池 3.2.1 什么是线程池 3.2.2 不要重复发明轮子:JDK 对线程池的支持 1. 固定大小的线程池 2. 计划任务 3.2.3 刨根究底:核心线程池的内部实现 ...
- 【实战Java高并发程序设计6】挑战无锁算法
我们已经比较完整得介绍了有关无锁的概念和使用方法.相对于有锁的方法,使用无锁的方式编程更加考验一个程序员的耐心和智力.但是,无锁带来的好处也是显而易见的,第一,在高并发的情况下,它比有锁的程序拥有更好 ...
- JAVA高并发程序设计(葛一鸣著)读书笔记
本文为JAVA高并发程序设计(葛一鸣著)读书笔记.这本书对于刚刚入门的童鞋来讲可能有点深,我推荐可以先看看Java多线程编程核心技术(高洪岩著)一书. 第一章 走入并行世界 什么是同步和异步? 同步就 ...
- Java高并发程序设计入门
转自:http://blog.csdn.net/johnstrive/article/details/50667557 说在前面 本文绝大部分参考<JAVA高并发程序设计>,类似读书笔记和 ...
- 《实战Java高并发程序设计》github笔记和源码
笔记 <实战Java高并发程序设计>中有很多代码范例,适合初学者通过实践入门并发编程,这本书有个问题就是前面的代码都用JDK7,第六章开始又用JDK8了 笔者做了相关笔记并整理源代码,欢迎 ...
- java unsafe获取指针_【实战Java高并发程序设计 1】Java中的指针:Unsafe类
是<实战Java高并发程序设计>第4章的几点. 如果你对技术有着不折不挠的追求,应该还会特别在意incrementAndGet() 方法中compareAndSet()的实现.现在,就让我 ...
- 《实战Java高并发程序设计》.pdf
关注"Java后端技术全栈" 回复"面试"获取全套面试资料 如今,秒杀已经变得十分常见,我们也都习以为常. 然而,从技术的角度来说,秒杀对于Web系统是一个巨大 ...
- 今天开始拜读一本大神写的书《实战Java高并发程序设计 》
基本信息 书名:实战Java高并发程序设计 定价:69.00元 作者:葛一鸣著 出版社:电子工业出版社 出版日期:2015-10-01 ISBN:9787121273049 字数:493000 页码: ...
- 实战java高并发程序设计-笔记进行中
<JAVA并发编程实践>:出书时间太早,内容比较散,专业术语翻译较早和现在有差异 <Java并发编程的艺术>:手绘图较多文字内容较少,主要讲解并发实现的底层原理和面临的问题,底 ...
最新文章
- webservice服务器端获取request对象的三种方式
- linux mysql 知乎_在 Linux 上安装 MariaDB 或 MySQL | Linux 中国
- 网络爬虫(2)-- Java爬虫框架
- Git 添加到Git 仓库
- Java Integer的缓存策略
- Extjs 4.2 MVC+ThreeJs学习笔记(二)一个简单的ThreeJS场景
- 1.微信小程序-B站:前言准备
- 每日长难句打卡Day23
- pageoffice 选中部分文字 添加书签和空白处添加书签 删除空白以及内容书签
- 《创新者的窘境》读书笔记
- 删除Mac右上角可恶的状态栏图标
- 亮瞎眼的十六进制颜色代码表
- 下拉菜单选择城市列表html,js弹出式下拉列表框选择省市地区美化插件 - pickout.js...
- 服务器设置自动开机及定时开机
- 苹果手机黑屏怎么办,苹果手机不能开机怎么办
- 【498. 对角线遍历】
- MATLAB直接输出棋盘格标定板
- 成都理工大学计算机考研经历,09计算机考研的小小体会~
- 微生物组学研究手段概览2——宏基因组和宏转录组
- 关于matlab的相关性函数