`

JUC(java.util.concurrent)要点笔记

    博客分类:
  • Java
阅读更多
    • iteye没落了,编辑格式太难整,表格位置有问题,图片无法上传
  • 线程

    线程6种状态 java.lang.Thread.State:
  • NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

启动线程的3种方式:Thread类、Runnable接口、Executor线程池(实际工作中推荐使用这种方式:see《阿里巴巴Java开发手册(终极版)》一、编程规约-(六)并发处理-条目3

 

1个Java进程至少2个线程:main、GC

 

wait 和 sleep区别(JUC版sleep: 用TimeUnit类,例如TimeUnit.SECONDS.sleep(2)):

  wait sleep
调用者 Object对象 Thread类静态调用
释放锁 Y N
使用范围 与notify成组使用、用于线程通信 单独使用、哪里都可以用
异常捕获 可以不捕获 需捕获

 

 

  • synchronized 和 Lock 区别:

  synchronized java.util.concurrent.locks.Lock
语法 关键字 接口
尝试获取锁 N、若A获得则B一直等待 Y、可尝试获取若失败则放弃
自动释放锁 Y N
公平锁 N 默认非公平、可设置
精准控制 N、适合代码量小的同步 Y
  • synchronized锁的是谁?static synchronized 或 synchronized(xxx.class) 锁的是class模板对象、否则锁的是调用者。

  • 线程编码口诀:线程操作资源类

  • Callable接口与Runnable区别

         
      synchronized Runnable
    返回值 Y N
    声明抛出异常 Y
    注:当线程池中Callable任务运行异常时、异常会被抛到外部、外部可通过ExecutionException捕捉到
    N
    注:当线程池中Runnable任务运行异常时、异常不会被抛到外部、需在run方法中处理

Future接口

   
方法 含义
get() 获取结果(阻塞)
get(long timeout, TimeUnit unit) 在指定时间内获取结果(阻塞)
isDone() 任务是否已完成(非阻塞)
cancel(boolean mayInterruptIfRunning) 取消任务,并返回命令是否发送成功
注:只要发送成功就返回true,和任务是否确实被取消无关
isCancelled() 任务是否已被取消
注:
1.当使用cancel(false)时,isCancelled()=true也不表示任务已中断;
2.当使用cancel(true)时,isCancelled()=true也不表示任务已中断,是否中断成功依赖于 if (Thread.currentThread().isInterrupted()) 代码块

 

线程通信

 

  • 线程之间通信:判断、执行、通知

  • 虚假唤醒问题:使用while进行条件判断

  • 生产者/消费者问题synchronized和JUC版实现对比:

  synchronized JUC版
判断条件 Object Condition
等待方法 wait await
通知方法 notify/notifyAll signal/signalAll

 

读写锁:

独占锁(写锁):一次只能被一个线程占有
共享锁(读锁):该锁可以被多个线程占有

自旋锁

偏向锁

 

 

常用辅助类

Semaphore 信号量

用途:多线程共享资源争夺、并发线程数量控制、多生产者/多消费者模式;

注意事项:

  1. 创建对象时传入的permits仅仅是初值,可通过多次调用release动态增加permits

  2. 创建对象时可传参控制是否公平,默认为非公平

         
方法 可被中断 不会被中断 尝试获得(非阻塞) 指定时间内尝试获得
获得 acquire()
acquire(int permits)
acquireUninterruptibly()
acquireUninterruptibly(int permits)
tryAcquire()
tryAcquire(int permits)
tryAcquire(long timeout, TimeUnit unit)
tryAcquire(int permits, long timeout, TimeUnit unit)
释放 release()
release(int permits)
     

其他方法:

   
方法 含义
availablePermits() 当前可用许可数
drainPermits() 获取并返回立即可用的许可数、并将可用许可数清零
getQueueLength() 取得等待许可的线程数
hasQueuedThreads() 判断是否有线程在等待许可

Exchanger 交换器

用途:2个线程之间传输数据

   
方法 说明
exchange(V x) 没有其他线程来取数据则会阻塞
exchange(V x, long timeout, TimeUnit unit) 指定时间内没有其他线程来取数据,则抛出java.util.concurrent.TimeoutException

CountDownLatch 减法计数器

用途:控制线程间同步,当计数器变为0的时候继续运行,否则阻塞。

注意事项:计数器无法重置

     
方法 说明 抛出异常
await()
await(long timeout, TimeUnit unit)
进入等待状态 InterruptedException
countDown() 计数器-1  

CyclicBarrier 加法计数器

用途:控制线程间同步,当计数器达到指定值的时候继续运行,否则阻塞。

     
方法 说明 抛出异常
await() 进入等待状态 InterruptedException
BrokenBarrierException
await(long timeout, TimeUnit unit) 进入等待状态有限时间 InterruptedException
BrokenBarrierException
TimeoutException
getNumberWaiting() 返回已到达屏障点的线程数,
注意:最后一个线程已到达时会返回0;
即假设parties=3,线程1,2 await()方法之后调用getNumberWaiting()=1,2,而线程3 await()方法之后调用getNumberWaiting()=0
 
getParties() 屏障对象个数  
reset() 重置屏障,等待屏障的其他线程会出现BrokenBarrierException  

CountDownLatch和CyclicBarrier区别:

CountDownLatch使用情况为2个角色互等、CyclicBarrier使用情况为同类互等。

 

Phaser 移相器(CyclicBarrier增强版) since1.7

用途:CyclicBarrier增强版、可动态增减parties计数,可用于线程分组同步控制。

   
方法 说明
arrive() 使getArrivedParties()+1,且不等待其他线程,并重置计数器
awaitAdvance(int phase) 如果参数phase值和当前getPhase()方法返回值一致则等待,否则继续运行,类似旁观者作用,可被中断但不会影响其他线程运行,不抛出InterruptedException
awaitAdvanceInterruptibly(int phase) 如果参数phase值和当前getPhase()方法返回值一致则等待,否则继续运行,可被中断但不会影响其他线程运行,抛出InterruptedException
awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) 同上,timeout时会抛出TimeoutException
arriveAndAwaitAdvance() 计数不足时会阻塞
arriveAndDeregister() 退出计数,并使parties-1
getPhase() 获取已到达屏障的对象个数
getRegisteredParties() 获取注册的parties数
register() parties+1
bulkRegister(int parties) 批量增加parties
getArrivedParties() 获取已经被使用的parties数
getUnarrivedParties() 获取还未被使用的parties数
forceTermination() 取消屏障,线程继续执行后续,不出现异常
isTerminated() 屏障是否已取消

 

线程池

线程池编码速记口诀:3大方法(实际工作中不推荐直接使用:see《阿里巴巴Java开发手册(终极版)》一、编程规约-(六)并发处理-条目4)、7大参数、4种拒绝策略

 

 

线程池大小/线程数

线程池大小与处理器的利用率之比估算公式:N-threads = N-CPU * U-CPU * (1 + W/C)
其中:
❑N-CPU是处理器的核的数目=Runtime.getRuntime().availableProcessors()
❑U-CPU是期望的CPU利用率(该值应该介于0和1之间)
❑W/C是等待时间与计算时间的比率

 

线程数设定:

  • CPU密集型(计算密集型):

    最大线程数=CPU核数=Runtime.getRuntime().availableProcessors(); 推荐使用Stream接口。

  • IO密集型:

    最大线程数=IO任务的倍数、不能低于IO任务的数量;使用CompletableFuture灵活性更好。

execute和submit方法区别

     
  execute submit
返回值 N Y
异常 默认直接抛出、不能捕获,可通过ThreadFactory方式进行捕获 默认可通过catch (ExecutionException e)捕获

CompletionService

用途:避免FutureTask阻塞缺点,更有效地处理Future返回值。

   
方法 说明
take() 获取已完成任务的Future(非阻塞),但当存在有任务未能完成时 take().get() 仍会阻塞
poll() 获取并移除已完成任务的Future,不存在则返回null(非阻塞)
poll(long timeout, TimeUnit unit) 等待指定时间,无论结果如何均往下执行

 

Fork-Join 分支合并 since1.7

 

2步骤:任务拆分、结果合并。

应用场景:大数据量,好处:提高效率、坏处:产生资源争夺

原理:工作窃取(work-stealing)算法、底层使用双端队列

 

 

集合/队列

 不安全集合类 安全集合类
ArrayList CopyOnWriteArrayList
HashSet CopyOnWriteArraySet
HashMap ConcurrentHashMap
  • 4组API:队列一般可以检测第一个元素是谁!

 方法  第一组会抛出异常  返回一个布尔值,不会抛出异常  延时等待  一直等待(阻塞)
插入 add() offer(e) offer(e,time) put()
取出 remove() poll() poll(time) take()
检查 element() peek() - -

 

非阻塞队列7个

阻塞队列6个

 

 

since 1.8

CompletableFuture 异步回调

函数式编程(java.util.function)

 

lambda表达式:()->{}

4个基本的函数式接口:

  • Function : 有一个输入参数有一个输出参数

  • Consumer:有一个输入参数,没有输出参数

  • Supplier:没有输入参数,只有输出参数

  • Predicate:有一个输入参数,判断是否正确

Stream(java.util.stream)

  • 流:从支持数据处理操作的源生成的一系列元素。

  • 2类流操作:中间操作、终端操作。

  • 流利用内部迭代:迭代通过filter、map、sorted等操作被抽象掉了,filter、map等中间操作会返回一个流,并可以链接在一起,可以用来设置一条流水线,但不会生成结果。

  • forEach和count等终端操作会返回一个非流的值,并处理流水线以返回结果。

  • 流中的元素是按需计算的。

 阅读《Java 8 in Action》、《Java 8函数式编程》

 

单例模式实现对比

       
实现方式 可延迟加载 多线程环境安全 会被反射破坏
饿汉式 N Y Y
懒汉式 Y N Y
懒汉式+synchronized Y Y   但性能低下 Y
DCL懒汉式 Y Y   但可能产生NPE Y
DCL懒汉式+volatile Y Y Y
Holder方式 Y Y Y
枚举类式 N Y N
枚举类+Holder方式 Y Y Y

原子引用

java.util.concurrent.atomic包

ABA问题

 

 
分享到:
评论

相关推荐

    java.util.concurrent 测试源文件

    Java.util.concurrent(JUC)是Java平台中的一个核心包,专门用于处理多线程并发问题。这个包包含了大量的工具类和接口,极大地简化了并发编程的复杂性,提高了程序的性能和可伸缩性。本测试源文件主要是针对JUC并发...

    JUC2019.6V1.5.zip

    首先我们知道,JUC就是java.util.concurrent包,俗称java并发包,那首先我们要知道java并发包是用来干嘛 的,然后要知道java并发包包括哪些知识点,这些知识点在平常中有哪些重要的运用,简单来说,这个学习 方法...

    java7rt.jar源码-JVM:JVM学习笔记

    java.util.concurrent java.util.concurrent java.util.locks java.util.atomic 进程/线程 并发/并行 线程 package com.ntuzy.juc_01 ; import java.util.concurrent.Callable ; import java.util.concurrent....

    JUC学习笔记 .md

    import java.util.concurrent.locks.ReentrantLock; public class Ticket { private final ReentrantLock lock = new ReentrantLock(); public void sale() { lock.lock(); try { // 执行售票逻辑 } ...

    尚硅谷JUC视频笔记整理,很详细和全面,帮你迅速掌握JUC

    JUC(Java Util Concurrent),即Java的并发工具包,是Java提供的一套并发编程解决方案,它通过一系列接口和类简化了并发编程的复杂性。本笔记整理涉及了JUC的内存可见性、volatile关键字以及CAS算法和原子变量等多...

    Java并发体系知识导图笔记.xmind

    J.U.C并发包,即java.util.concurrent包,是JDK的核心工具包,是JDK1.5之后,由 Doug Lea实现并引入。

    个人学习JUC代码笔记总集

    Java并发编程领域中的JUC(Java Util Concurrency)是一门深奥且实用的技术,它包含在Java的`java.util.concurrent`包中,为多线程编程提供了高效、易用的工具。这个压缩包文件“个人学习JUC代码笔记总集”显然是一...

    尚硅谷大厂面试题第二季周阳主讲整理笔记

    Java并发编程主要涉及java.util.concurrent包,包括并发工具类、原子类和锁。其中: - **java.util.concurrent** 包含并发工具类,如ExecutorService、Semaphore、CountDownLatch等。 - **java.util.concurrent....

    狂神说JUC.pdf

    JUC(Java Util Concurrent)是Java中用于并发编程的工具包,它提供了一系列用于多线程编程的类和接口,以帮助开发者实现高效的多线程程序。在并发编程中,我们需要理解几个核心概念,比如线程和进程,以及它们之间...

    JUC并发编程.md

    import java.util.concurrent.locks.ReentrantLock; public class TicketSale { private final ReentrantLock lock = new ReentrantLock(); private int tickets = 100; // 假设共有100张票 public void ...

    狂神说JUC代码狂神说JUC代码

    【狂神说JUC代码】是一系列专注于Java并发编程(JUC,Java Util Concurrency)的教程或笔记,旨在帮助开发者深入理解并掌握Java平台上的并发处理机制。JUC是Java标准库中的一组高级并发工具类,为多线程环境下的程序...

    Concurrent.zip

    在IT行业中,尤其是在Java开发领域,`java.util.concurrent`(JUC)包是并发编程的核心工具包,它提供了丰富的类和接口,使得开发者能够高效、安全地处理多线程环境中的任务。`Concurrent.zip`文件很可能是包含了...

    笔记_Java并发编程(2).docx

    Java并发工具集(JUC,java.util.concurrent)提供了丰富的并发组件,如`ExecutorService`、`Future`、`BlockingQueue`等,帮助开发者高效地编写并发程序。 并发编程的挑战在于正确地管理线程间的通信和同步,避免...

    java并发编程学习笔记

    Java中的线程池主要通过`java.util.concurrent`包下的`ExecutorService`接口及其实现类`ThreadPoolExecutor`来实现。 #### 三、`ThreadPoolExecutor`原理 `ThreadPoolExecutor`是Java中最常用的线程池实现类之一,...

    Java很好的学习笔记4 无锁.md,学习代码

    无锁编程,也称为Lock-Free Programming,是指在多线程环境下,通过避免使用传统的锁机制(如synchronized或java.util.concurrent.locks.Lock)来同步对共享数据的访问。这种技术依赖于原子操作(如CAS - Compare ...

    java并发编程笔记

    ### Java并发编程笔记 #### 一、线程与进程 - **进程**: 是操作系统资源分配的基本单位,每个进程都有自己的独立内存空间。例如,当我们打开QQ或者音乐播放器时,实际上是在启动`qq.exe`或`Music.exe`这样的程序,...

    Java并发包源码分析(JDK1.8)

    Java并发包源码分析(JDK1.8):囊括了java.util.concurrent包中大部分类的源码分析,其中涉及automic包,locks包(AbstractQueuedSynchronizer、ReentrantLock、ReentrantReadWriteLock、LockSupport等),queue...

    周阳大神高级+面试经验+Java面试题.txt

    根据提供的文件信息,我们可以推断出这是一份与Java高级面试相关的资料,主要涉及JVM、JUC(Java Util Concurrency)以及Java多线程高并发等知识点。下面将对这些核心内容进行详细阐述。 ### JVM精讲 #### 1. JVM...

    JUC多线程学习个人笔记

    Java Util Concurrent(JUC)是Java并发编程的核心库,提供了丰富的工具和接口,使得开发者能够高效、安全地处理多线程环境中的并发问题。以下将详细介绍JUC中的关键概念和特性。 1. **线程池**:JUC通过Executor...

Global site tag (gtag.js) - Google Analytics