juc

Java多线程之JUC包:AbstractQueuedSynchronizer(AQS)源码学习笔记

ⅰ亾dé卋堺 提交于 2020-01-20 08:51:16
若有不正之处请多多谅解,并欢迎批评指正。 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/go2sea/p/5618628.html AbstractQueuedSynchronizer(AQS)是一个同步器框架,在实现锁的时候,一般会实现一个继承自AQS的内部类sync,作为我们的自定义同步器。AQS内部维护了一个state成员和一个队列。其中state标识了共享资源的状态,队列则记录了等待资源的线程。以下这五个方法,在AQS中实现为直接抛出异常,这是我们自定义同步器需要重写的方法: ①isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。 ②tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败返回false。 ③tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败返回false。 ④tryAcquireShared(int):共享方式。尝试获取资源。成功返回true,失败返回false。 ⑤tryReleaseShared(int):共享方式。尝试释放资源,成功则返回true,失败返回false。 其中isHeldExclusively需要在使用Condition时重写

JUC(java.util.concurrent)

不羁的心 提交于 2020-01-19 04:45:17
在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。 一、volatile关键字、内存可见性 内存可见性 内存可见性(Memory Visibility)是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。 可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。 我们可以通过同步来保证对象被安全地发布。除此之外我们也可以使用一种更加轻量级的 volatile 变量。 volatile 关键字 Java 提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程,可以保证内存中的数据可见。可以将 volatile 看做一个轻量级的锁,但是又与锁有些不同: 对于多线程,不是一种互斥关系 不能保证变量状态的“原子性操作” public class TestVolatile { public static void main(String[] args

JUC源码分析-AQS

落爺英雄遲暮 提交于 2020-01-19 01:19:31
AbstractQueuedSynchronizer分析 AQS独占锁方法分析 互斥模式也可以称为独占模式,独占锁是互斥模式的实现(互斥模式的代码 在公平锁和非公平锁有讲解,这里不再详述) //互斥模式获取锁的模板方法, tryAcquire 尝试通过CAS方式获取锁,由子类实现。 public final void acquire (int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } //互斥模式获取锁的模板方法,如果当前线程被打断,抛出打断异常。 public final void acquireInterruptibly (int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); } //互斥模式获取锁的模板方法,如果指定纳秒内没有获得锁则中断获取,返回false。 public final boolean tryAcquireNanos (int arg, long

JUC 多线程

冷暖自知 提交于 2020-01-12 14:56:43
JUC ​ 在Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。 一、多线程回顾 线程和进程 ​ 程序是完成特定任务、用某种语言编写的一段代码,程序是静态的,程序运行后变为一个进程,进程是动态的。一个进程内可以有多个线程同时执行。进程是所有线程的集合,每一个线程是进程中的一条执行路径。 多线程的使用优势 ​ 提高应用程序的响应;提高 CPU 的利用率;改善冗长、复杂的程序结构;使用线程可以耗时任务放到后台去处理。 多线程的创建方式 方式一:继承 Thread 类 创建一个继承 Thread 类的子类 重写 Thread 类的 run() --> 将此线程执行的操作声明在 run() 中 创建 Thread 类的子类的对象 通过此对象调用 start():① 启动当前线程 ② 调用当前线程的 run() 方式二:实现 Runnable 接口 创建一个实现 Runnable 接口的类 实现类去实现 Runnable 中的抽象方法:run() 创建实现类的对象 将此对象作为参数传递到 Thread 类的构造器中,创建 Thread 类的对象

JUC 中的 Atomic 原子类总结

∥☆過路亽.° 提交于 2020-01-10 00:11:16
1 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。 所以,所谓原子类说简单点就是具有原子/原子操作特征的类。 并发包 java.util.concurrent 的原子类都存放在 java.util.concurrent.atomic 下,如下图所示。 根据操作的数据类型,可以将JUC包中的原子类分为4类 基本类型 使用原子的方式更新基本类型 AtomicInteger:整型原子类 AtomicLong:长整型原子类 AtomicBoolean :布尔型原子类 数组类型 使用原子的方式更新数组里的某个元素 AtomicIntegerArray:整型数组原子类 AtomicLongArray:长整型数组原子类 AtomicReferenceArray :引用类型数组原子类 引用类型 AtomicReference:引用类型原子类 AtomicReferenceFieldUpdater:原子更新引用类型里的字段 AtomicMarkableReference :原子更新带有标记位的引用类型 对象的属性修改类型 AtomicIntegerFieldUpdater

【零】JUC

懵懂的女人 提交于 2020-01-08 20:45:53
一、JUC 在 Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。 二、多线程 2.1 进程和线程 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码( 静态的 )。 进程(process)是程序的一次执行过程,或是正在运行的一个程序。进程是一个动态过程,即有它自身的产生、存在和消亡的过程。每个Java程序都有一个隐含的主程序,即main方法( 动态的,是线程的集合 )。 线程(thread),线程是进程内部的一条具体的执行路径。若一个程序可同一时间执行多个线程,就是支持多线程的(一 个线程是进程中的一条执行路径 )。 2.2 多线程的优势 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。 提高计算机系统CPU的利用率 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改 使用线程可以将耗时任务放到后台去处理,例如等待用户输入、文件读写和网络收发数据等。 2.3 线程安全 当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题

JUC之阻塞队列介绍

两盒软妹~` 提交于 2020-01-07 19:02:02
简介   在并发编程中,有时候需要使用线程安全的队列。   要实现一个线程安全的队列有两种方式: 1. 阻塞算法 ;    阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现。 2. 非阻塞算法 。    非阻塞的实现方式则可以使用循环CAS的方式来实现。   JUC中非阻塞队列有 ConcurrentLinked Queue 和 ConcurrentLinked Deque 。 本文主要介绍阻塞队列相关类和接口 阻塞队列   阻塞队列在实际应用中非常广泛,许多消息中间件中定义的队列,通常就是一种“阻塞队列”。    ConcurrentLinked Queue 和 ConcurrentLinked Deque 是以非阻塞算法实现的高性能队列,其使用场景一般在高并发环境下,需要“队列/栈”这类数据结构时才使用;   而 “阻塞队列” 通常利用了“锁”来实现,也就是会阻塞调用线程,其使用场景一般是在 “ 生产者-消费者 ” 模式中,用于线程之间的数据交换或系统解耦。   “生产者-消费者”这种模式中,“生产者” 和 “消费者” 是相互独立的,两者之间的通信需要依靠一个队列。这个队列就是要说的 阻塞队列。   引入“阻塞队列”的最大好处就是解耦,在软件工程中,“高内聚,低耦合”是进行模块设计的准则之一,这样“生产者”和“消费者

【JUC】JUC锁框架综述

蹲街弑〆低调 提交于 2019-12-25 01:58:24
一、前言   在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程。我们分为几个模块进行分析,首先是对锁模块的分析。 二、锁框架图   在Java并发中,锁是最重要的一个工具,因为锁,才能实现正确的并发访问,所以,先从锁入手一步步进行分析,锁的框架图如下。   说明:在锁结构框架中乃至并发框架中,AbstractQueuedSynchronizer都占有举足轻重的地位,同时LockSupport也是非常重要的类。 三、具体说明    3.1 Condition   Condition为接口类型,它将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。 可以通过await(),signal()来休眠/唤醒线程。    3.2 Lock   Lock为接口类型,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性

JUC 基础内容概述

半城伤御伤魂 提交于 2019-12-23 10:50:29
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Concurrent Programming in Java 的作者 Doug Lea 编写了一个极其优秀的、免费的并发实用程序包,它包括并发应用程序的锁、互斥、队列、线程池、轻量级任务、有效的并发集合、原子的算术操作和其它基本构件。我们一般称这个包为 J.U.C。 1. JUC概况 以下是Java JUC包的主体结构: Atomic : AtomicInteger Locks : Lock, Condition, ReadWriteLock Collections : Queue, ConcurrentMap Executer : Future, Callable, Executor Tools : CountDownLatch, CyclicBarrier, Semaphore 2. 原子操作 多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。出现原因: synchronized的代价比较高。 以下以AtomicInteger为例: int addAndGet(int delta):以原子方式将给定值与当前值相加。 实际上就是等于线程安全版本的i =i+delta操作。 boolean compareAndSet(int expect,

JUC(四)——强大的辅助类讲解

不羁岁月 提交于 2019-12-20 04:34:16
JUC(一)——Locks JUC(二)——深入理解锁机制 JUC(三)——线程安全类 JUC(四)——强大的辅助类讲解 JUC(五)——Callable JUC(六)——阻塞队列 JUC(七)——线程池简单使用 JUC(八)——线程池深入讲解 本篇文章主要讲解concurrent中的三个类 1、 CountDownLatch 2、 CyclicBarrier 3、 Semaphore 1、CountDownLatch 让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。 举例: 放学后班长负责锁门,班长必须要等到班里的学生都走了以后才能锁门 假设班长是main线程,教室里面有6个学生,班长要等学生走完之后锁门 public class CountDownLatchDemo { public static void main ( String [ ] args ) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch ( 6 ) ; //要等待的数量 for ( int i = 1 ; i <= 6 ; i ++ ) { final int tempI = i ; new Thread ( ( ) - > { System . out . println ( "同学" +