线程同步: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包相关推荐

  1. 廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合

    Concurrent 用ReentrantLock+Condition实现Blocking Queue. Blocking Queue:当一个线程调用getTask()时,该方法内部可能让给线程进入等 ...

  2. java多线程之Concurrent包

    1.在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题. 2.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的 ...

  3. java.util.concurrent包

    本文是我们学院课程中名为Java Concurrency Essentials的一部分 . 在本课程中,您将深入探讨并发的魔力. 将向您介绍并发和并发代码的基础知识,并学习诸如原子性,同步和线程安全之 ...

  4. Java高并发编程学习(三)java.util.concurrent包

    简介 我们已经学习了形成Java并发程序设计基础的底层构建块,但对于实际编程来说,应该尽可能远离底层结构.使用由并发处理的专业人士实现的较高层次的结构要方便得多.要安全得多.例如,对于许多线程问题,可 ...

  5. java.util.concurrent包API学习笔记

    newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...

  6. 【ArrayList】为什么java.util.concurrent 包里没有并发的ArrayList实现?

    2019独角兽企业重金招聘Python工程师标准>>> 为什么java.util.concurrent 包里没有并发的ArrayList实现? 问:JDK 5在java.util.c ...

  7. java concurrent包的学习(转)

    java concurrent包的学习(转) http://my.oschina.net/adwangxiao/blog/110188 我们都知道,在JDK1.5之前,Java中要进行业务并发时,通常 ...

  8. 高并发编程基础(java.util.concurrent包常见类基础)

    JDK5中添加了新的java.util.concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法 ...

  9. java的concurrent包

    2019独角兽企业重金招聘Python工程师标准>>> 最近在网上看到一个将concurrent包的系列文章,仔细读了一遍,感觉不错. 分享一下:http://www.hetaobl ...

最新文章

  1. BB陆逊高达(3Dmax)
  2. 6种常见的无线组网架构
  3. 电脑PDF怎么转换成WPS,这招你学会了
  4. Spring实战(前言:Spring容器)
  5. Appium——主从控制执行
  6. 推荐几个常用的生物通路数据库
  7. 树莓派 鼠标延迟问题【Linux】
  8. 大智慧 软件 开发语言_智慧工厂培训软件开发流程篇
  9. 喜大普奔,VS Code 开启远程开发新时代!
  10. 【Vue: 使用pdf.js顯示PDF Viewer】
  11. 给还在迷茫的你分享我从零基础的日语文科生半路出家搞Python如何上岸的
  12. php无法找到该页,UCHOME出现问题(转帖)
  13. java——jui的应用
  14. Android 兼容搜狗输入法 英文输入 回车监听无效的bug
  15. Linux基础系列(2命令帮助的详细获取)
  16. 蓝桥杯 算法提高 阮小二买彩票 Python
  17. 求n位水仙花数(C语言实现)
  18. macOS Big Sur 11.1 Beta1(20C5048i)原版镜像下载
  19. static关键字能修饰什么
  20. 智慧工业之化工厂人员定位系统为什么要采用RFID技术来实现?苏州新导为您解答化工厂难点

热门文章

  1. Ubuntu分别用ibus和scim安装五笔
  2. 网络摄像头3 cmos ov9650,plugins/input_s3c2410/
  3. Life Cycle Stages of ASP.NET Web Page.
  4. OGNL使用方法总结
  5. 带线的无限级下拉树列表-完整示例篇
  6. OSSIM中配置网络资产监控
  7. java FileReader/FileWriter读写文件
  8. [Lua学习]简单链表
  9. 安装open-vm-tools
  10. HashTable和HashMap的区别(网上整理)