juc

1、JUC系列之---线程基础

∥☆過路亽.° 提交于 2020-02-29 17:22:03
一、多线程概述 1、进程:正在进行中的程序 2、线程:就是进程中一个负责程序执行的控制单元(执行路径) 一个进程中,可以有多个执行路径,即多线程 一个进程中,至少有一个执行路径。 (多线程其实就是多个线程中的快速切换) 二、多线程的创建方式①--继承Thread类 继承Thread类,重写run方法 1、JVM创建的主线程的任务都定义在了主函数中 2、Thread类中的run方法就是封装自定义线程任务的函数,即run方法相当于一个main方法 package com.lee.juc; public class ThreadDemo_01 { public static void main(String[] args) { Demo demo1 = new Demo("张三"); Demo demo2 = new Demo("LeeSi"); demo1.start(); demo2.start(); System.out.println("=======结束========"); } } class Demo extends Thread{ private String name; @Override public void run() { for(int i=0;i<10;i++) { System.out.println(name+"====>"+i); } } public

3、JUC系列之---Concurrent

若如初见. 提交于 2020-02-29 17:04:57
一、卖票 需求:三个人卖30张票 代码: package com.lee.juc.concurrent; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SaleTicket { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"AA").start(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"BB").start(); new Thread(new Runnable() { public void run() { for(int i=0;i<100;i++) { ticket.sale(); } } },"CC").start(); } } //票 class Ticket{ private int

JUC学习之Lock同步锁

夙愿已清 提交于 2020-02-29 11:25:32
一、简介 引出Lock同步锁之前,先了解一下synchronized同步的一些缺陷: 如果一段代码被synchronized锁住,那么当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁。如果某个时刻获得锁的线程发生阻塞现象,那么这把锁会被它一直持有,而其他线程永远无法获取锁,正常来说,不能让其他线程永远在那里等待。 使用Lock锁的话,提供了一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断); 使用Lock锁的话,通过tryLock()方法可以尝试获取锁,这就知道线程有没有成功获取到锁; 基于上面Lock的两大优势,我们今天总结一下Lock同步锁相关的知识。 Lock是一个接口,源码如下: public interface Lock { //获取锁,如果锁已被其他线程获取,则进行等待。 void lock(); //当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态 void lockInterruptibly() throws InterruptedException; //尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false boolean tryLock(); //指定时间内尝试获取锁,在拿不到锁时会等待一定的时间

JUC学习之循环栅栏CyclicBarrier

爱⌒轻易说出口 提交于 2020-02-29 10:04:14
一、简介 前面已经简单介绍了CountDownLatch闭锁,本文的CyclicBarrier其实跟闭锁差不多,当然还是存在一些区别。 官网介绍如下: CyclicBarrier是一种同步辅助工具,允许一组线程彼此等待到达一个共同的障碍点。CyclicBarrier在包含固定大小的线程的程序中非常有用,这些线程有时必须彼此等待。这个屏障被称为循环屏障,因为它可以在等待的线程被释放后重新使用。 CyclicBarrier支持一个可选的Runnable命令,该命令在在最后一个线程到达之后,但是在释放任何线程之前执行,这个屏障动作对于在任何一方继续之前更新共享状态非常有用。 通俗理解,就是CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。在CyclicBarrier类的内部有一个计数器,每个线程在到达屏障点的时候都会调用await方法将自己阻塞,此时计数器会减1,当计数器减为0的时候,所有因调用await方法而被阻塞的线程将被唤醒。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用(栅栏可重复使用)。 二、常见API 构造方法: //创建一个新的CyclicBarrier,当给定数量的参与方(线程)正在等待它时,它将会跳闸,并且在跳闸时不会执行预定义的操作。 CyclicBarrier(int parties) /

多线程进阶——JUC并发编程之CountDownLatch源码一探究竟

ぃ、小莉子 提交于 2020-02-28 11:17:32
1、学习切入点 JDK的并发包中提供了几个非常有用的并发工具类。 CountDownLatch 、 CyclicBarrier 和 Semaphore 工具类提供了一种并发流程控制的手段。本文将介绍CountDownLatch(闭锁)的实现原理。在了解闭锁之前需要先了解AQS,因为CountDownLatch的实现需要依赖于AQS共享锁的实现机制。 官方文档: https://docs.oracle.com/javase/8/docs/api/ 百度翻译如下: 一种同步辅助程序,允许一个或多个线程等待在其它线程中执行的一组操作完成。使用给定的计数初始化CountDownLatch。由于调用了countDown()方法,await方法阻塞直到当前计数为零,之后释放所有等待线程,并立即返回await的任何后续调用。这是一个一次性现象——计数不能重置。如果需要重置计数的版本,请考虑使用CyclicBarrier。倒计时锁存器是一种通用的同步工具,可用于多种目的。使用计数1初始化的倒计时锁存器用作简单的开/关锁存器或门:调用倒计时()的线程打开它之前,调用它的所有线程都在门处等待。初始化为N的倒计时锁存器可用于使一个线程等待N个线程完成某个操作或某个操作已完成N次。倒计时锁存器的一个有用特性是,它不要求调用倒计时的线程在继续之前等待计数达到零

JUC并发编程(十)-阻塞队列BlockingQueue

老子叫甜甜 提交于 2020-02-28 10:39:13
10、阻塞队列:BlockingQueue 10.1. 阻塞队列概念 队列:排队 特性:先进先出 FIFO 阻塞:必须要阻塞、不得不阻塞,原理如下: 10.2. 接口架构图 jdk官方文档如下: 阻塞队列:与List、Set类似,都是继承Collection. 10.3.ArrayBlockingQueue API 的使用 1、ArrayBlockingQueue 是一个有限的 blocking queue ,由数组支持。 2、这个队列排列元素FIFO(先进先出)。 3、队列的 头部 是队列中最长时间的元素。队列的 尾部 是队列中最短时间的元素。 4、新元素插入队列的尾部,队列检索操作获取队列头部的元素。 5、这是一个经典的“有界缓冲区”,其中固定大小的数组保存由生产者插入的元素并由消费者提取。 6、队列的固定大小创建后,容量无法更改。 ​ ArrayBlockingQueue 以插入方法、移除方法、检查队首三个方法为单元,形成了四组API,分别是抛出异常组、返回特殊值组、超时退出组、一直阻塞组,如下: ​ 方法 抛出异常 返回特殊值 超时退出 一直阻塞 插入(存) add offer offer(e, timeout, unit) put () 移除(取) remove poll poll(timeout, unit) take() 检查队首 element peek - - ​

多线程进阶——JUC并发编程之CyclicBarrier源码一探究竟

て烟熏妆下的殇ゞ 提交于 2020-02-28 05:37:30
1、学习切入点 百度翻译大概意思就是: 一种同步辅助程序,允许一组线程相互等待到达一个公共的屏障点。CyclicBarrier在涉及固定大小的线程方的程序中非常有用,这些线程方有时必须相互等待。这个屏障被称为循环屏障,因为它可以在等待的线程被释放后重新使用。 CyclicBarrier支持可选的Runnable命令,该命令在参与方中的最后一个线程到达后,但在释放任何线程之前,每个屏障点运行一次。此屏障操作有助于在任何参与方继续之前更新共享状态。 动图演示: 在上文中我们分析完了 CountDownLatch源码 ,可以理解为 减法计数器 ,是基于 AQS的共享模式 使用,而CyclicBarrier相比于CountDownLatch 来说,要简单很多,它类似于 加法计数器 ,在源码中使用 ReentrantLock 和 Condition 的组合 来使用。 2、案例演示 CyclicBarrier //加法计数器 public class CyclicBarrierDemo { public static void main(String[] args) { /** * 集齐5名队员,开始游戏 */ // 开始战斗的线程 CyclicBarrier cyclicBarrier = new CyclicBarrier(5,()->{ System.out.println(

JUC包中的锁框架

天大地大妈咪最大 提交于 2020-02-27 08:52:56
 JUC包中的锁,包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件,AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁。由于CountDownLatch,CyclicBarrier和Semaphore也是通过AQS来实现的;因此,我也将它们归纳到锁的框架中进行介绍。   先看看锁的框架图,如下所示。 01. Lock接口   JUC包中的 Lock 接口支持那些语义不同(重入、公平等)的锁规则。所谓语义不同,是指锁可是有"公平机制的锁"、"非公平机制的锁"、"可重入的锁"等等。"公平机制"是指"不同线程获取锁的机制是公平的",而"非公平机制"则是指"不同线程获取锁的机制是非公平的","可重入的锁"是指同一个锁能够被一个线程多次获取。 02. ReadWriteLock   ReadWriteLock 接口以和Lock类似的方式定义了一些读取者可以共享而写入者独占的锁。JUC包只有一个类实现了该接口,即 ReentrantReadWriteLock,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的

JUC中的原子操作类及其原理

百般思念 提交于 2020-01-31 03:46:37
  昨天简单的看了看Unsafe的使用,今天我们 看看 JUC中的原子类是怎么使用Unsafe的,以及分析一下其中的原理! 一.简单使用AtomicLong   还记的上一篇博客中我们使用了volatile关键字修饰了一个int类型的变量,然后两个线程,分别对这个变量进行10000次+1操作,最后结果不是20000,现在我们改成AtomicLong之后,你会发现结果始终都是20000了!有兴趣的可以试试,代码如下 package com.example.demo.study; import java .util.concurrent.atomic.AtomicLong; public class Study0127 { // 这是一个全局变量,注意,这里使用了一个原子类AtomicLong public AtomicLong num = new AtomicLong(); // 每次调用这个方法,都会对全局变量加一操作,执行10000次 public void sum() { for ( int i = 0; i < 10000; i++ ) { // 使用了原子类的incrementAndGet方法,其实就是把num++封装成原子操作 num.incrementAndGet(); System.out.println( "当前num的值为num= "+ num); } }

多线程JUC包之CountDownLatch

拥有回忆 提交于 2020-01-29 23:51:48
CountDownLatch 用来控制一个或者多个线程等待多个线程。 内部使用了一个计数器,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。 import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; public class CountDownLatchExample { public static long a = 0; public static void main(String[] args) throws InterruptedException { final int threadSize = 1000; final CountDownLatch countDownLatch = new CountDownLatch(threadSize); AtomicInteger atomicInteger=new AtomicInteger();//原子性类 ExecutorService