高级concurrent包
线程同步:1. 多线程读写竞争资源需要同步2. Java语言提供了synchronized/wait/notify来实现线程的同步3. 但是编写多线程的同步仍然很困难所以JDK提供的高级的java.util.concurrent包1. concurrent包可以提供更高级的同步功能2. 同时可以简化多线程程序的编写3. JDK1.5提供的
因为synchronized是JAVA提供的,所以不需要考虑异常.但是如果我们使用ReentrantLock,是一个普通的JAVA类,所以我们要用try...finally的这样的结构来保证锁的释放,
首先我们new ReentrankLock()来创建一个对象,然后我们要试图用lock.lock()方法获取锁,如果我们获取成功,就进入try代码,在finally里面使用lock.unlock()来释放锁.这里必须要注意的是lock.lock()必须在try之外完成.因为lock.lock()方法可能会失败,而unlock方法一定要在finally里面完成ReentrantLock也是一种可重入的锁:1. 可重入的锁,一个线程可多次获取同一个锁2. lock()方法就是用来获取锁的3. tryLock()方法可尝试获取锁并可指定超时使用ReentrankLock比synchronized更安全synchronized要么获得锁,要么永远的等待下去,而使用ReentrankLock的时候,我们可以使用tryLock()在失败的时候,不会导致死锁.
package com.leon.day05;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class Counter {// 首先初始化一个ReentrantLock实例,然后向上转型为Lock接口private Lock lock = new ReentrantLock();private int value = 0;public void add(int m) {lock.lock();try { this.value += m;}finally {lock.unlock();}}public void dec(int m) {lock.lock();try {this.value -= m;}finally {lock.unlock();}}public int get() {lock.lock();try {return this.value;}finally {lock.unlock();}}}public class Main {final static int LOOP = 100;// 在main方法中启动两个线程,分别调用add和dec方法,public static void main(String[] args) throws InterruptedException {Counter counter = new Counter();Thread t1 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.add(1);}}};Thread t2 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.dec(1);}}};t1.start();t2.start();t1.join();t2.join();System.out.println(counter.get());}}
ReentrantLock可以替代synchronizedReentrantLock获取锁更安全必须使用try...finally保证正确获取和释放锁
临界区就是任何时候只有一个线程能够执行的代码块,但是有些时候这种保护有点过头任何时候只允许一个线程修改,对inc()方法加锁也是必须的,但是get()方法只读取数据,不修改数据,允许多个线程同时调用我们希望允许多个线程同时读,但只要一个线程在写,其他线程就必须等待.多线程同时读是允许的,我们只是不允许多线程同时写,或者同时读写.我们可以使用ReadWriteLock可以解决:1. 只允许一个线程写入,(其它线程既不能写入也不能读取)2. 但是在没有线程写入的时候,多个线程允许同时读(提高性能)
首先创建一个ReadWriteLock的实例,然后分别获取readLock()和writeLock().变量rLock代表readLock,而wLock代表writeLock,在写方法中使用wLock.lock()加锁而在读方法中使用rLock.lock()加锁,这样我们就可以大大的提高读取的效率.
package com.leon.day05;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;class Counter {// 首先创建一个ReadWriteLock的实例private ReadWriteLock lock = new ReentrantReadWriteLock();// 然后通过readLock获取读锁private Lock rLock = lock.readLock();// 通过writeLock获取写锁private Lock wLock = lock.writeLock();private int value = 0;// add方法是一个修改方法,所以用wLock,解锁加锁public void add(int m) {wLock.lock();try { this.value += m;}finally {wLock.unlock();}}// 对于dec方法也是写锁public void dec(int m) {wLock.lock();try {this.value -= m;}finally {wLock.unlock();}}// 但是对于get方法只需要使用一个读锁,这样多个线程就可以获取读锁public int get() {rLock.lock();try {return this.value;}finally {rLock.unlock();}}}public class Main {final static int LOOP = 100;// 在main方法中启动两个线程,分别调用add和dec方法,public static void main(String[] args) throws InterruptedException {Counter counter = new Counter();Thread t1 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.add(1);}}};Thread t2 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.dec(1);}}};t1.start();t2.start();t1.join();t2.join();System.out.println(counter.get());}}
ReadWriteLock适用的条件:1. 适用同一个实例,有大量线程读取,仅有少数线程修改:例如一个论坛的帖子,浏览可以看成是读取,但是非常频繁的,发布写入是不频繁的. 这种情况下就可以使用ReadWriteLock.
使用ReadWriteLock可以提高读取的效率1. ReadWrite只允许一个线程写入2. 但是允许多个线程同时读取3. 特别适合读多写少的场景
高级concurrent包相关推荐
- 廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合
Concurrent 用ReentrantLock+Condition实现Blocking Queue. Blocking Queue:当一个线程调用getTask()时,该方法内部可能让给线程进入等 ...
- java多线程之Concurrent包
1.在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题. 2.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的 ...
- java.util.concurrent包
本文是我们学院课程中名为Java Concurrency Essentials的一部分 . 在本课程中,您将深入探讨并发的魔力. 将向您介绍并发和并发代码的基础知识,并学习诸如原子性,同步和线程安全之 ...
- Java高并发编程学习(三)java.util.concurrent包
简介 我们已经学习了形成Java并发程序设计基础的底层构建块,但对于实际编程来说,应该尽可能远离底层结构.使用由并发处理的专业人士实现的较高层次的结构要方便得多.要安全得多.例如,对于许多线程问题,可 ...
- java.util.concurrent包API学习笔记
newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...
- 【ArrayList】为什么java.util.concurrent 包里没有并发的ArrayList实现?
2019独角兽企业重金招聘Python工程师标准>>> 为什么java.util.concurrent 包里没有并发的ArrayList实现? 问:JDK 5在java.util.c ...
- java concurrent包的学习(转)
java concurrent包的学习(转) http://my.oschina.net/adwangxiao/blog/110188 我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常 ...
- 高并发编程基础(java.util.concurrent包常见类基础)
JDK5中添加了新的java.util.concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法 ...
- java的concurrent包
2019独角兽企业重金招聘Python工程师标准>>> 最近在网上看到一个将concurrent包的系列文章,仔细读了一遍,感觉不错. 分享一下:http://www.hetaobl ...
最新文章
- BB陆逊高达(3Dmax)
- 6种常见的无线组网架构
- 电脑PDF怎么转换成WPS,这招你学会了
- Spring实战(前言:Spring容器)
- Appium——主从控制执行
- 推荐几个常用的生物通路数据库
- 树莓派 鼠标延迟问题【Linux】
- 大智慧 软件 开发语言_智慧工厂培训软件开发流程篇
- 喜大普奔,VS Code 开启远程开发新时代!
- 【Vue: 使用pdf.js顯示PDF Viewer】
- 给还在迷茫的你分享我从零基础的日语文科生半路出家搞Python如何上岸的
- php无法找到该页,UCHOME出现问题(转帖)
- java——jui的应用
- Android 兼容搜狗输入法 英文输入 回车监听无效的bug
- Linux基础系列(2命令帮助的详细获取)
- 蓝桥杯 算法提高 阮小二买彩票 Python
- 求n位水仙花数(C语言实现)
- macOS Big Sur 11.1 Beta1(20C5048i)原版镜像下载
- static关键字能修饰什么
- 智慧工业之化工厂人员定位系统为什么要采用RFID技术来实现?苏州新导为您解答化工厂难点