序号 备注 核心代码 适用场景
1 synchronized 同步锁

并发锁加在方法级别上,如果是单例class对象,则只能允许一个线程进入
public synchronized void doXXX(){ … }
加在对象上,则与此对象相同的对象都不允许进入该锁的代码块:
synchronized(this){ … }

排斥相同锁对象进入并发代码块
2 Semaphore  信号量锁  final Semaphore semaphore = new Semaphore(2,true); //示例new一个对象,指定2个信号量,表示可以允许同时有2个线程进入信号量锁代码块。

semaphore.acquire(); //获取锁,获取不到锁则阻塞。由构造函数的数字决定允许有几个线程可以并发获得这个锁。也就是允许几个线程可以进入这个并发锁持有的代码块。
semaphore.release(); //释放锁,放别的线程进入信号量锁代码块。

 控制线程并发进入某代码块数量
3  CountDownLatch  共享锁  final CountDownLatch countDownLatch = new CountDownLatch(1); //这里的数字代表需要扣减几次才能执行锁内代码块

countDownLatch.await(); //线程堵塞,等待执行controller.countDown();代码
countDownLatch.countDown(); //每执行一次,则new此对象时的构造函数给的数字减去1,直到减去结果等于0,执行countDownLatch.await();之后原本阻塞的代码块,相当于signal()唤醒操作。

 在执行过程中,需要其他已知数量的N个数据作为解除当前线程阻塞的条件。
4  Exchanger  交换器  创建Exchanger交换器对象,用来同步producer生产者和consumer消费者

Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
List<String> producerList = new ArrayList<String>();//创建生产者
List<String> consumerList = new ArrayList<String>();//创建消费者
生产者集合里放入数据后,数据交换给exchanger交换器,生产者集合回归为空
producerList = exchanger.exchange(producerList);
消费者集合从exchanger交换器中实时获取数据,进行处理。
consumerList = exchanger.exchange(consumerList);

生产者和消费者可以控制到一定数量后使用交换器进行交换。
如果不控制数量,始终只允许一个数据进行生产进而消费,可以考虑使用SynchronousQueue

5  CyclicBarrier  栅栏锁  定义一个最后执行的线程类:

class DoFinalThread implements Runnable { public void run() { … } }
DoFinalThread dfThread = new DoFinalThread();
创建栅栏锁barrier。此对象会等待5个线程。当5个线程结束后,它会执行dfThread线程对象。
CyclicBarrier barrier=new CyclicBarrier(5,dfThread);
barrier.await(); //每执行一次,barrier对象计数器从5里面-1,直到减到值为0,就可以执行dfThread线程对象
注意:当dfThread线程对象执行完毕之后,又会去执行那5个线程里barrier.await();后面的代码,因为之前被阻塞了。

在同一个点同步任务。

在执行过程中,需要其他已知数量的N个线程执行完毕,最后再执行指定的一个线程。

6  locks.LockSupport  阻塞锁  LockSupport.park(); //使当前线程安全阻塞

LockSupport.unpark(threadA); //解锁:唤醒阻塞的指定线程

当需要额外线程中的数据参与执行当前线程时。
当心死锁:当额外线程的解锁语句执行早于当前线程的阻塞语句时,会发生死锁。

7 Phaser 阶段同步锁

Phaser phaser = new Phaser(3); //new一个阶段锁,表示将会有3个线程并发参与这些分阶段执行的任务。
phaser.arriveAndAwaitAdvance();// 通知phaser对象当前线程已经完成了当前阶段,需要被阻塞直到其他线程也都完成当前阶段,才继续执行后面代码。小技巧:可以放在每个线程开始的时候执行这个代码,保证不会在所有线程尚未创建完毕时就有某些线程已经开始执行。
phaser.arriveAndDeregister(); //通知phaser对象当前线程已经结束了这个阶段,并且将不再参与接下来的阶段操作。Phaser中唯一一种减少线程参与者数量的方法。
phaser.isTerminated(); //阶段锁是否已终止,返回true: 不再有任何线程在执行任何阶段,所有线程都已经执行完毕phaser.arriveAndDeregister();
phaser.register(); //将一个新的参与者线程注册到Phaser中对象,当phaser对象被某一线程持有引用对象后,就可以调用这个注册方法把该线程注册进来当前阶段。
onAdvance(); //重写Phaser父类方法,如果需要在切换阶段时执行指定事件的话。

适用于并发任务,且需要将任务分解成多个步骤分阶段同步完成业务。
8 ReentrantLock lock同步锁

ReentrantLock lock = new ReentrantLock(true); //true表示先到的线程先获得锁,锁获得的公平机制
queueLock.lock(); //只允许一个线程进入该lock之后的代码块
queueLock.unlock(); //释放锁,允许其他一个线程进入lock代码块
boolean boo = lock.hasQueuedThreads(); //判断是否有线程正在等待获取这个锁
int len = lock.getQueueLength(); //有几个线程正在等待获取这个锁
Collection<Thread> lockedThreads = lock.getThreads(); //返回所有正在等待获取这个锁的线程

 只允许单个线程执行某个代码块
9 ReadWriteLock 读写锁  ReadWriteLock lock = new ReentrantReadWriteLock();

lock.readLock().lock(); //写锁为独占锁,只能允许单个线程进入临界区(之后的代码块),并且排斥读锁
lock.readLock().unlock(); //释放写锁,允许其他单个线程进入临界区
lock.writeLock().lock(); //读锁为共享锁,允许多个线程进入临界区,但是如果写锁被某线程占用,则读锁获取失败,线程进入阻塞。
lock.writeLock().unlock();//写锁释放

 在多个线程间需要同步值,并且读写互斥
10 Condition 条件锁

ReentrantLock lock = new ReentrantLock(true); //lock同步锁
Condition c = lock.newCondition(); //条件锁要在lock同步锁临界区中才会起作用
c.await(); //使当前线程进入睡眠状态
c.signalAll(); //唤醒使用了c这个对象进入睡眠的所有线程
c.signal(); 唤醒一个等待的线程。如果有线程在此条件下等待,那么将选择一个线程进行唤醒。

 使线程有条件地进入睡眠状态,有条件的唤醒

java.util.concurrent包下并发锁的特点与适用场景的更多相关文章

  1. java.util.concurrent包下集合类的特点与适用场景

    java.util.concurrent包,此包下的集合都不允许添加null元素 序号 接口 类 特性 适用场景 1 Queue.Collection ArrayBlockingQueue 有界.阻塞 ...

  2. Java并发编程之java.util.concurrent包下常见类的使用

    一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class Co ...

  3. Java中java.util.concurrent包下的4中线程池代码示例

    先来看下ThreadPool的类结构 其中红色框住的是常用的接口和类(图片来自:https://blog.csdn.net/panweiwei1994/article/details/78617117 ...

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

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

  5. 线程并发线程安全介绍及java.util.concurrent包下类介绍

    线程Thread,在Java开发中多线程是必不可少的,但是真正能用好的并不多! 首先开启一个线程三种方式 ①new Thread(Runnable).start() ②thread.start(); ...

  6. 【并发编程】【JDK源码】JDK的(J.U.C)java.util.concurrent包结构

    本文从JDK源码包中截取出concurrent包的所有类,对该包整体结构进行一个概述. 在JDK1.5之前,Java中要进行并发编程时,通常需要由程序员独立完成代码实现.当然也有一些开源的框架提供了这 ...

  7. 深入理解java:2.3. 并发编程 java.util.concurrent包

    JUC java.util.concurrent包, 这个包是从JDK1.5开始引入的,在此之前,这个包独立存在着,它是由Doug Lea开发的,名字叫backport-util-concurrent ...

  8. java.util.concurrent包

    在JavaSE5中,JUC(java.util.concurrent)包出现了 在java.util.concurrent包及其子包中,有了很多好玩的新东西: 1.执行器的概念和线程池的实现.Exec ...

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

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

随机推荐

  1. ABP框架(asp.net core 2.X+Vue)模板项目学习之路(二)--切换MySql数据库

    前言: 大家好,今天给大家带来ABP第二篇的分享,在写这篇分享的时候非常的困难,因为发现ABP的框架越是深入.难度也就越大,而且深刻感觉到自己领域驱动开发知识的欠缺,前段时间买了两本有关于领域驱动知识 ...

  2. [转载] Fiddler为所欲为第三篇 封包逆向必备知识[三]

    导语: 小A同学:会抓包有什么好学习的,不就用一个工具设置个wifi代{过}{滤}理就OK了嘛,还不是很多做不了.不如学习安卓逆向.didi科学家:不好意思,抓包可以为所欲为. 其实学习抓包,完完全全 ...

  3. Spring 注入集合

    Spring 中,注入集合类型的数值方式 <bean id="javaCollection" class="com.qie_zi.JavaCollection&qu ...

  4. PostgreSQL注入基础

    一般注入多用于在mssql和mysql两类数据库中,如mssql+asp.mysql+php则是最为常见的搭配环境.不同的网站应用的数据库也大不一样,根据数据库的处理能力.负载等多重因素决定.本文主要 ...

  5. 周强 201771010141《面对对象程序设计(java)》第十周学习总结

    ---恢复内容开始--- 1.实验目的与要求 (1) 理解泛型概念: (2) 掌握泛型类的定义与使用: (3) 掌握泛型方法的声明与使用: (4) 掌握泛型接口的定义与实现: (5)了解泛型程序设计, ...

  6. 2018—自学Selenium+Python 笔记(二)

    此文记录一些python语法不同之处.. 适合有研发基础的童鞋查阅.. 零基础的童鞋就怪怪一个个学吧! 记录也不一定全,随笔一记 多行语句 total=item1+\ item2+\ item3 &q ...

  7. 查询MySQL数据库中表结构的几种方法

    什么是表结构?表结构就是定义数据表文件名,确定数据表包含哪些字段,各字段的字段名.字段类型.及宽度,并将这些数据输入到计算机当中. 查询方法:以表‘employees’为例子 1.describe(d ...

  8. js bind0

    $(function(){ $("#ul").on('click','li',function(){ if(!$(this).a $(function(){ $("#ul ...

  9. jQuery-3.事件篇---键盘事件

    jQuery键盘事件之keydown()与keyup()事件 鼠标有mousedown,mouseup之类的事件,这是根据人的手势动作分解的2个触发行为.相对应的键盘也有这类事件,将用户行为分解成2个 ...

  10. sqlalchemy关于时间的数据类型

    #导入模块 from sqlalchemy import Column, Integer, String, Date, create_engine from sqlalchemy.ext.declar ...