juc

JUC——线程同步辅助工具类(Semaphore,CountDownLatch,CyclicBarrier)

爷,独闯天下 提交于 2019-11-30 18:10:13
CountDownLatch CountDownLatch是一个计数器闭锁,通过它可以完成类似于阻塞当前线程的功能,即:一个线程或多个线程一直等待,直到其他线程执行的操作完成。CountDownLatch用一个给定的计数器来初始化,该计数器的操作是原子操作,即同时只能有一个线程去操作该计数器。调用该类await方法的线程会一直处于阻塞状态,直到其他线程调用countDown方法使当前计数器的值变为零,每次调用countDown计数器的值减1。当计数器值减至零时,所有因调用await()方法而处于等待状态的线程就会继续往下执行。这种现象只会出现一次,因为计数器不能被重置,如果业务上需要一个可以重置计数次数的版本,可以考虑使用CycliBarrier。 在某些业务场景中,程序执行需要等待某个条件完成后才能继续执行后续的操作;下面举个栗子,比如秦国需要灭六国才能一统华夏。 代码示例: public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 1; i <= 6; i++) { new Thread(() ->

JUC知识图

女生的网名这么多〃 提交于 2019-11-29 12:11:40
JUC 分为5大类 tools:Lock; collections:Queue CopyOnWriteArrayList locks:ReadWriteLock atomic:AtomicBoolean executor:Future Callable 来源: https://www.cnblogs.com/chenbensheng/p/11517367.html

JUC 一 CyclicBarrier 与 Semaphore

空扰寡人 提交于 2019-11-29 10:19:00
java.util.concurrent CyclicBarrier简介 CyclicBarrier:可重用屏障/栅栏 类似于 CountDownLatch(倒计数闭锁),它能阻塞一组线程直到某个事件的发生。 与闭锁的关键区别在于,所有的线程必须同时到达屏障位置,才能继续执行。 CountDownLatch 的计数器只能使用一次,而 CyclicBarrier 的计数器可以使用 reset() 方法重置 CountDownLatch 采用减计数方式,CyclicBarrier 采用加计数方式 CyclicBarrier源码 构造函数: //线程到达屏障时,优先执行 barrierAction public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } public CyclicBarrier(int parties) { this(parties, null); } await(),await(long timeout, TimeUnit

Mysql高手系列 - 第9篇:详解分组查询,mysql分组有大坑!

倾然丶 夕夏残阳落幕 提交于 2019-11-29 09:13:50
这是Mysql系列第9篇。 环境:mysql5.7.25,cmd命令中进行演示。 本篇内容 分组查询语法 聚合函数 单字段分组 多字段分组 分组前筛选数据 分组后筛选数据 where和having的区别 分组后排序 where & group by & having & order by & limit 一起协作 mysql分组中的坑 in多列查询的使用 分组查询 语法: SELECT column, group_function,... FROM table [WHERE condition] GROUP BY group_by_expression [HAVING group_condition]; 说明: group_function:聚合函数。 group_by_expression:分组表达式,多个之间用逗号隔开。 group_condition:分组之后对数据进行过滤。 分组中,select后面只能有两种类型的列: 出现在group by后的列 或者使用聚合函数的列 聚合函数 函数名称 作用 max 查询指定列的最大值 min 查询指定列的最小值 count 统计查询结果的行数 sum 求和,返回指定列的总和 avg 求平均值,返回指定列数据的平均值 分组时,可以使用使用上面的聚合函数。 准备数据 drop table if exists t_order; --

JUC之CountDownLatch和CyclicBarrier的区别 (转)

╄→гoц情女王★ 提交于 2019-11-29 00:04:27
CountDownLatch和CyclicBarrier的功能看起来很相似,不易区分,有一种谜之的神秘。本文将通过通俗的例子并结合代码讲解两者的使用方法和区别。 CountDownLatch和CyclicBarrier都是java.util.concurrent包下面的多线程工具类。 从字面上理解,CountDown表示减法计数,Latch表示门闩的意思,计数为0的时候就可以打开门闩了。Cyclic Barrier表示循环的障碍物。两个类都含有这一个意思:对应的线程都完成工作之后再进行下一步动作,也就是大家都准备好之后再进行下一步。然而两者最大的区别是,进行下一步动作的动作实施者是不一样的。这里的“动作实施者”有两种,一种是主线程(即执行main函数),另一种是执行任务的其他线程,后面叫这种线程为“其他线程”,区分于主线程。对于CountDownLatch,当计数为0的时候,下一步的动作实施者是main函数;对于CyclicBarrier,下一步动作实施者是“其他线程”。 下面举例说明: 对于CountDownLatch,其他线程为游戏玩家,比如英雄联盟,主线程为控制游戏开始的线程。在所有的玩家都准备好之前,主线程是处于等待状态的,也就是游戏不能开始。当所有的玩家准备好之后,下一步的动作实施者为主线程,即开始游戏。 我们使用代码模拟这个过程,我们模拟了三个玩家

JUC探险-6、Lock & AQS

丶灬走出姿态 提交于 2019-11-28 22:16:58
文章目录 一、:Lock初步认识   Lock提供的方法 二、:AQS   ①AQS的设计模式     1、AQS提供的模板方法可以分为三类     2、在新建一个同步组件时需要把握的两个关键点     3、同步组件以及AQS的功能实际上被切分成各自的两部分   ②同步队列   ③独占式锁     1、独占式锁常用方法     2、独占锁的获取——acquire()方法       Ⅰ、addWaiter()方法       ⅰ、enq()方法       Ⅱ、acquireQueued()方法       ⅰ、shouldParkAfterFailedAcquire()方法       ⅱ、parkAndCheckInterrupt()方法     3、独占锁的释放——release()方法       Ⅰ、unparkSuccessor()方法     4、独占锁的可中断式获取——acquireInterruptibly()方法       Ⅰ、doAcquireInterruptibly()方法     5、独占锁的超时等待式获取——tryAcquireNanos()方法       Ⅰ、doAcquireNanos()方法   ④共享式锁     1、共享式锁常用方法     2、共享锁的获取——acquireShared()方法       Ⅰ

java高并发系列 - 第32天:高并发中计数器的实现方式有哪些?

拟墨画扇 提交于 2019-11-28 19:49:13
这是java高并发系列第32篇文章。 java环境:jdk1.8。 本文主要内容 4种方式实现计数器功能,对比其性能 介绍LongAdder 介绍LongAccumulator 需求:一个jvm中实现一个计数器功能,需保证多线程情况下数据正确性。 我们来模拟50个线程,每个线程对计数器递增100万次,最终结果应该是5000万。 我们使用4种方式实现,看一下其性能,然后引出为什么需要使用 LongAdder 、 LongAccumulator 。 方式一:synchronized方式实现 package com.itsoku.chat32; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.LongAccumulator; /** * 跟着阿里p7学并发,微信公众号:javacode2018 */ public class Demo1 { static int count = 0;

JUC-多线程锁

时光总嘲笑我的痴心妄想 提交于 2019-11-28 17:45:51
1 标准访问,先打印短信还是邮件 2 停4秒在短信方法内,先打印短信还是邮件 3 普通的hello方法,是先打短信还是hello 4 现在有两部手机,先打印短信还是邮件 5 两个静态同步方法,1部手机,先打印短信还是邮件 6 两个静态同步方法,2部手机,先打印短信还是邮件 7 1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件 8 1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件 运行答案: 1、短信 2、短信 3、Hello 4、邮件 5、短信 6、短信 7、邮件 8、邮件 A 一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了, 其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法 锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法 加个普通方法后发现和同步锁无关 换成两个对象后,不是同一把锁了,情况立刻变化。 synchronized实现同步的基础:Java中的每一个对象都可以作为锁。 具体表现为以下3种形式。 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前类的Class对象。 对于同步方法块,锁是 Synchonized 括号里配置的对象

JUC 一 线程池

孤人 提交于 2019-11-28 15:53:16
线程 线程,是程序执行的最小单元。线程是进程中的其中一个实体,是被系统独立调度和分派的基本单位 线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源 它可与同属一个进程的其它线程共享进程所拥有的全部资源。 一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。 并发与并行 并发:一个应用程序的多个线程可以是并发的 并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序(或线程)之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。 所有的并发处理都有排队等候,唤醒,执行等这样的步骤 并行:并行是多个应用程序在同一时间运行,例如在多核处理器上。 并不存在像并发那样竞争,等待的概念。 多线程 一个应用程序有一个以上的线程,我们把这种情况就称之为多线程。 线程池 线程池是指在初始化一个多线程应用程序过程中创建一个线程集合 然后在需要执行新的任务时重用这些线程而不是新建一个线程(提高线程复用,减少性能开销) 线程使用完回到池子中,然后等待下一次分配任务。 线程池作用就是限制系统中执行线程的数量。 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。 用线程池控制线程数量,其他线程排队等候。 Java线程池框架 线程池分为三种: 基础线程池ThreadPoolExecutor

JUC 一 CopyOnWriteArrayList 和 CopyOnWriteArraySet

£可爱£侵袭症+ 提交于 2019-11-28 13:56:53
CopyOnWriteArrayList 是一个线程安全的 ArrayList ,通过内部的 volatile数组 和 显式锁ReentrantLock 来实现线程安全。 CopyOnWriteArraySet 是线程安全的 Set ,它是由 CopyOnWriteArrayList 实现,内部持有一个 CopyOnWriteArrayList 引用,所有的操作都是由 CopyOnWriteArrayList 来实现的,区别就是 CopyOnWriteArraySet 是无序的,并且不允许存放重复值。 适用场景 适合元素比较少,并且读取操作高于更新(add/set/remove)操作的场景 由于每次更新需要复制内部数组,所以更新操作开销比较大 内部的迭代器 iterator 使用了“快照”技术,存储了内部数组快照, 所以它的 iterator 不支持remove、set、add操作,但是通过迭代器进行并发读取时效率很高。 源码 /** * The lock protecting all mutators. (We have a mild preference * for builtin monitors over ReentrantLock when either will do.) */ final transient Object lock = new Object(); /*