- 浏览: 38601 次
-
最新评论
java JUC包小结
1 软件包 java.util.concurrent 的描述
1,执行程序
接口。Executor 是一个简单的标准化接口,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。根据所使用的具体 Executor 类的不同,可能在新创建的线程中,现有的任务执行线程中,或者调用 execute() 的线程中执行任务,并且可能顺序或并发执行。ExecutorService 提供了多个完整的异步任务执行框架。ExecutorService 管理任务的排队和安排,并允许受控制的关闭。ScheduledExecutorService 子接口添加了对延迟的和定期任务执行的支持。ExecutorService 提供了安排异步执行的方法,可执行由 Callable 表示的任何函数,结果类似于 Runnable。Future 返回函数的结果,允许确定执行是否完成,并提供取消执行的方法。
实现。类 ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 提供可调的、灵活的线程池。Executors 类提供大多数 Executor 的常见类型和配置的工厂方法,以及使用它们的几种实用工具方法。其他基于 Executor 的实用工具包括具体类 FutureTask,它提供 Future 的常见可扩展实现,以及 ExecutorCompletionService,它有助于协调对异步任务组的处理。
2,队列
java.util.concurrent ConcurrentLinkedQueue 类提供了高效的、可伸缩的、线程安全的非阻塞 FIFO 队列。java.util.concurrent 中的五个实现都支持扩展的 BlockingQueue 接口,该接口定义了 put 和 take 的阻塞版本:LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue、PriorityBlockingQueue 和 DelayQueue。这些不同的类覆盖了生产者-使用者、消息传递、并行任务执行和相关并发设计的大多数常见使用的上下文。
3,并发 Collection
除队列外,此包还提供了几个设计用于多线程上下文中的 Collection 实现:ConcurrentHashMap、CopyOnWriteArrayList 和 CopyOnWriteArraySet。
此包中与某些类一起使用的“Concurrent&rdquo前缀;是一种简写,表明与类似的“同步”类有所不同。例如,java.util.Hashtable 和 Collections.synchronizedMap(new HashMap()) 是同步的,但 ConcurrentHashMap 则是“并发的”。并发集合是线程安全的,但是不受单个排他锁定的管理。在 ConcurrentHashMap 这一特定情况下,它可以安全地允许进行任意数目的并发读取,以及数目可调的并发写入。需要通过单个锁定阻止对集合的所有访问时,“同步”类是很有用的,其代价是较差的可伸缩性。在期望多个线程访问公共集合的其他情况中,通常“并发”版本要更好一些。当集合是未共享的,或者仅保持其他锁定时集合是可访问的情况下,非同步集合则要更好一些。
大多数并发 Collection 实现(包括大多数 Queue)与常规的 java.util 约定也不同,因为它们的迭代器提供了弱一致的,而不是快速失败的遍历。弱一致的迭代器是线程安全的,但是在迭代时没有必要冻结集合,所以它不一定反映自迭代器创建以来的所有更新。
4.1计时
TimeUnit 类为指定和控制基于超时的操作提供了多重粒度(包括纳秒级)。该包中的大多数类除了包含不确定的等待之外,还包含基于超时的操作。在使用超时的所有情况中,超时指定了在表明已超时前该方法应该等待的最少时间。在超时发生后,实现会“尽力”检测超时。但是,在检测超时与超时之后再次实际执行线程之间可能要经过不确定的时间。
4.2同步器
四个类可协助实现常见的专用同步语句。Semaphore 是一个经典的并发工具。CountDownLatch 是一个极其简单但又极其常用的实用工具,用于在保持给定数目的信号、事件或条件前阻塞执行。CyclicBarrier 是一个可重置的多路同步点,在某些并行编程风格中很有用。Exchanger 允许两个线程在集合点交换对象,它在多流水线设计中是有用的。
5,软件包 java.util.concurrent.atomic
类的小工具包,支持在单个变量上解除锁定的线程安全编程。
6,软件包 java.util.concurrent.locks
为锁定和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。
2,自己的一些总结
java.util.concurrent.atomic包
1,线程安全的基础原子类 AtomicBoolean, AtomicInteger, AtomicLong,AtomicIntegerArray,AtomicLongArray,AtomicReference,AtomicReferenceArray
2,*FieldUpdater反射的volatile(不太明白) AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater
3,带版本管理的Reference类 AtomicMarkableReference,AtomicStampedReference
java.util.concurrent.locks包
其实语法自带的synchronized锁在大部分情况下足够用了,比较灵活的场景下才需要使用这些特殊的锁。
1,Lock.java接口
java.util.concurrent包
TimeUnit,计算时间的单位,秒
java的内存模型
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4
4.1 计时、4.2 同步器 的使用
主要包括5个类,Semaphore, CountDownLatch, CyclicBarrier, Exchanger, TimeUnit
Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问
按此方式使用时,二进制信号量具有某种属性(与很多 Lock 实现不同),即可以由线程释放“锁定”,而不是由所有者(因为信号量没有所有权的概念)。在某些专门的上下文(如死锁恢复)中这会很有用。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
例用法: 下面给出了两个类,其中一组 worker 线程使用了两个倒计数锁存器:
第一个类是一个启动信号,在 driver 为继续执行 worker 做好准备之前,它会阻止所有的 worker 继续执行。
第二个类是一个完成信号,它允许 driver 在完成所有 worker 之前一直等待。
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse(); // don't let run yet
startSignal.countDown(); // let all threads proceed
doSomethingElse();
doneSignal.await(); // wait for all to finish
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
另一种典型用法是,将一个问题分成 N 个部分,用执行每个部分并让锁存器倒计数的 Runnable 来描述每个部分,然后将所有 Runnable 加入到 Executor 队列。当所有的子部分完成后,协调线程就能够通过 await。(当线程必须用这种方法反复倒计数时,可改为使用 CyclicBarrier。)
class Driver2 { // ...
void main() throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(N);
Executor e = ...
for (int i = 0; i < N; ++i) // create and start threads
e.execute(new WorkerRunnable(doneSignal, i));
doneSignal.await(); // wait for all to finish
}
}
class WorkerRunnable implements Runnable {
private final CountDownLatch doneSignal;
private final int i;
WorkerRunnable(CountDownLatch doneSignal, int i) {
this.doneSignal = doneSignal;
this.i = i;
}
public void run() {
try {
doWork(i);
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
CyclicBarrier
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。
public class Exchanger<V>extends Object两个线程可以交换对象的同步点。每个线程都在进入 exchange 方法时给出某个对象,并接受其他线程返回时给出的对象。
public enum TimeUnitextends Enum<TimeUnit>TimeUnit 表示给定单元粒度的时间段,它提供在这些单元中进行跨单元转换和执行计时及延迟操作的实用工具方法。
1,
Lock lock = ...;
if ( lock.tryLock(50L, TimeUnit.MILLISECONDS) ) ...
2,
TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 10000)); //thread.sleep的便捷使用
4.1 计时、4.2 同步器 的原理
5,死循环的自旋锁,无锁定的并发
3,一些自测试的代码
测试CyclicBarrier
package com.mike.juc; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; /** * TODO Comment of CyclicBarrierTest */ public class CyclicBarrierTest { final int N; final int[][] data; final CyclicBarrier barrier; private int[] result; class Worker implements Runnable { private int index; private int[] oneRow; Worker(int[] data, int index) { this.index = index; this.oneRow = data; } public void run() { try { TimeUnit.MILLISECONDS.sleep((long) (Math.random() * 10000)); // Thread.sleep((long) (Math.random() * 10000)); } catch (InterruptedException e) { } System.out.println("start " + index + " row!"); int rowResult = 0; for (int i = 0, length = oneRow.length; i < length; i++) { rowResult += oneRow[i]; } result[index] = rowResult; try { System.out.println("finish " + index + " row, result = " + rowResult); barrier.await(); } catch (InterruptedException ex) { return; } catch (BrokenBarrierException ex) { return; } } } public CyclicBarrierTest(int[][] matrix) { data = matrix; N = matrix.length; result = new int[N]; barrier = new CyclicBarrier(N, new Runnable() { public void run() { int total = 0; for (int i = 0, length = result.length; i < length; i++) { total += result[i]; } System.out.println("total result:" + total); } }); } public void start() { for (int i = 0; i < N; ++i) { Thread thread = new Thread(new Worker(data[i], i)); // thread.setDaemon(true); thread.start(); } System.out.println("abc"); } public static void main(String[] args) { int[][] matrix = { { 1, 2, 3 }, { 2, 3, 4 }, { 3, 4, 5 } }; new CyclicBarrierTest(matrix).start(); } }
package com.mike.juc; import java.util.concurrent.Exchanger; /** * TODO Comment of ExchangerTest */ public class ExchangerTest { Exchanger<String> exchanger = new Exchanger<String>(); class FillingLoop implements Runnable { public void run() { String currentBuffer = "123"; System.out.println("===" + Thread.currentThread().getId() + "\tcurrentBuffer=" + currentBuffer); try { currentBuffer = exchanger.exchange(currentBuffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("===" + Thread.currentThread().getId() + "\tcurrentBuffer=" + currentBuffer); } } class EmptyingLoop implements Runnable { public void run() { String currentBuffer = "124"; System.out.println(Thread.currentThread().getId() + "\tcurrentBuffer=" + currentBuffer); try { currentBuffer = exchanger.exchange(currentBuffer); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getId() + "\tcurrentBuffer=" + currentBuffer); } } void start() { new Thread(new FillingLoop()).start(); new Thread(new EmptyingLoop()).start(); } public static void main(String[] args) { new ExchangerTest().start(); } }
package com.mike.juc; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; /** * TODO Comment of LockSupportTest * */ public class LockSupportTest { private AtomicBoolean locked = new AtomicBoolean(false); private Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>(); public void lock() { boolean wasInterrupted = false; Thread current = Thread.currentThread(); waiters.add(current); // Block while not first in queue or cannot acquire lock while (waiters.peek() != current || !locked.compareAndSet(false, true)) { LockSupport.park(); if (Thread.interrupted()) // ignore interrupts while waiting wasInterrupted = true; } waiters.remove(); if (wasInterrupted) // reassert interrupt status on exit current.interrupt(); } public void unlock() { locked.set(false); LockSupport.unpark(waiters.peek()); } public static void main(String[] args) { LockSupportTest lockSupportTest = new LockSupportTest(); for (int i = 0; i < 2; i++) { new Thread(new Runlock(lockSupportTest), "i=" + i).start(); } lockSupportTest.unlock(); } } class Runlock implements Runnable { private LockSupportTest lockSupportTest; /** * @param lockSupportTest */ public Runlock(LockSupportTest lockSupportTest) { this.lockSupportTest = lockSupportTest; } @Override public void run() { lockSupportTest.lock(); } }
测试Object 锁机制:
package com.mike.juc; import java.util.concurrent.TimeUnit; /** * TODO Comment of ObjectTest */ public class ObjectTest { private Object obj = new Object(); public void getAndWait() { System.out .println("thread id" + Thread.currentThread().getId() + "\tgetAndWait position 0"); synchronized (obj) { System.out.println("thread id" + Thread.currentThread().getId() + "\tgetAndWait position 1"); try { obj.wait(); } catch (InterruptedException e) { } System.out.println("thread id" + Thread.currentThread().getId() + "\tgetAndWait position 2"); } System.out .println("thread id" + Thread.currentThread().getId() + "\tgetAndWait position 4"); } public void notifyOneThread() { synchronized (obj) { try { obj.notify(); System.out.println("thread id" + Thread.currentThread().getId() + "\tnotifyOneThread"); } catch (Exception e) { } } } public static void main(String[] args) throws InterruptedException { System.err.println("main 1"); ObjectTest objectTest = new ObjectTest(); for (int i = 0; i < 10; i++) { new Thread(new WaitThread(objectTest)).start(); } System.err.println("main 2"); TimeUnit.SECONDS.sleep(10l); System.err.println("main 3"); for (int i = 0; i < 10; i++) { objectTest.notifyOneThread(); TimeUnit.SECONDS.sleep(1l); System.err.println("main 3.5"); } System.err.println("main 4"); } } class WaitThread implements Runnable { private ObjectTest objectTest; public WaitThread(ObjectTest objectTest) { this.objectTest = objectTest; } @Override public void run() { objectTest.getAndWait(); } } //从运行结果看,notify的解锁是有序的,先到先解 //main 1 //thread id8 getAndWait position 0 //thread id8 getAndWait position 1 //thread id9 getAndWait position 0 //thread id9 getAndWait position 1 //thread id10 getAndWait position 0 //thread id10 getAndWait position 1 //thread id11 getAndWait position 0 //thread id11 getAndWait position 1 //thread id12 getAndWait position 0 //thread id12 getAndWait position 1 //thread id13 getAndWait position 0 //thread id13 getAndWait position 1 //thread id14 getAndWait position 0 //thread id14 getAndWait position 1 //thread id15 getAndWait position 0 //thread id15 getAndWait position 1 //thread id16 getAndWait position 0 //thread id16 getAndWait position 1 //main 2 //thread id17 getAndWait position 0 //thread id17 getAndWait position 1 //main 3 //thread id1 notifyOneThread //thread id8 getAndWait position 2 //thread id8 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id9 getAndWait position 2 //thread id9 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id10 getAndWait position 2 //thread id10 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id11 getAndWait position 2 //thread id11 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id12 getAndWait position 2 //thread id12 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id13 getAndWait position 2 //thread id13 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id14 getAndWait position 2 //thread id14 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id15 getAndWait position 2 //thread id15 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id16 getAndWait position 2 //thread id16 getAndWait position 4 //main 3.5 //thread id1 notifyOneThread //thread id17 getAndWait position 2 //thread id17 getAndWait position 4 //main 3.5 //main 4
测试 Semaphore
package com.mike.juc; import java.util.concurrent.Semaphore; /** * TODO Comment of Pool */ public class Pool { private static final int MAX_AVAILABLE = 100; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throws InterruptedException { available.acquire(); return getNextAvailableItem(); } public void putItem(Object x) { if (markAsUnused(x)) available.release(); } // Not a particularly efficient data structure; just for demo protected Object[] items = new String[MAX_AVAILABLE]; protected boolean[] used = new boolean[MAX_AVAILABLE]; protected synchronized Object getNextAvailableItem() { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) { used[i] = true; return items[i]; } } return null; // not reached } protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) { if (item == items[i]) { if (used[i]) { used[i] = false; return true; } else return false; } } return false; } }
相关推荐
自己学习过程对Java JUC包知识的总结,看完并理解基本能应付各种基本的问题点,墙裂推荐分享 博客跳转链接: https://blog.csdn.net/qq_35642036/article/details/82767070
Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....
JUC(Java.util.concurrent)是Java并发编程库的一个重要组成部分,专门提供了在多线程环境下用于控制并发执行的工具类和接口。本篇内容将详细介绍JUC中的一些核心组件及其使用方法,包括CountDownLatch、Executors...
尚硅谷_JUC线程高级_源码、课件 ·1. 尚硅谷_JUC线程高级_volatile 关键字与内存可见性 ·2. 尚硅谷_JUC线程高级_原子变量与 CAS 算法 ·3. 尚硅谷_JUC线程高级_模拟 CAS 算法 ·4. 尚硅谷_JUC线程高级_同步容器类...
### Java多线程和JUC知识点详解 #### Lambda表达式与函数式编程 Lambda表达式是Java 8引入的一个重要特性,它支持将函数作为参数传递到方法中,极大地简化了代码编写。Lambda表达式的使用使得Java语言更加简洁、易...
教程视频:在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步 IO 和轻量级任务框架;还提供了设计用于多线程上下文...
Java并发编程库(Java Util Concurrency,简称JUC)是Java平台中用于高效并发处理的重要工具包,包含在`java.util.concurrent`包下。JUC提供了丰富的并发原语,如线程池、同步器、并发容器等,极大地简化了多线程...
为了解决这些问题,并进一步提高多线程程序的编写效率与可维护性,Java 5引入了JUC(Java Util Concurrency)包。JUC包提供了大量高级并发工具类,这些工具类简化了多线程编程的难度,使得开发者能够更加专注于业务...
JUC,全称为Java Util Concurrency,是Java并发包的简称,包含了大量用于处理并发问题的类和接口,极大地简化了多线程环境下的编程。在这个深度解析JUC线程锁框架的主题中,我们将探讨其核心组件、设计模式以及如何...
该项目为Java JUC框架下的售票系统设计源码,包含25个文件,其中包括23个Java源文件、1个属性文件和1个XML文件。项目涵盖了乘务员售票、一锁八式、Lock锁和多线程通信等多线程技术实践,旨在通过源码学习提升并发...
### JUC并发编程中的虚假唤醒及其解决方案 #### 一、虚假唤醒的概念与原理 在Java并发编程中,尤其是在处理多线程同步时,一个重要的概念是“虚假唤醒”(Spurious Wakeup)。这是一种较为罕见的现象,但在实际...
Java并发编程是Java开发中的重要领域,而Java.util.concurrent(JUC)工具包则是Java并发编程的核心组件。这个集合提供了一系列高效、线程安全的类和接口,用于简化多线程环境下的编程任务。本资源"JUC代码收集,...
此篇文章对应周阳老师的大厂面试教程,几乎包含了大厂所有JUC部分的面试题,虽然自己无缘大厂,但是这些知识也让我在面试中得到了不错的评价
首先我们知道,JUC就是java.util.concurrent包,俗称java并发包,那首先我们要知道java并发包是用来干嘛 的,然后要知道java并发包包括哪些知识点,这些知识点在平常中有哪些重要的运用,简单来说,这个学习 方法...
为了解决原子性问题,可以使用Java的Atomic包,如AtomicInteger、AtomicLong等,它们基于CAS操作,可以避免指令重排,保证多线程环境中的数据一致性。 **锁机制** 除了volatile,Java还提供了Lock接口及其实现,如...
### 小结 以上内容涵盖了尚硅谷提供的最新 Java 视频教程中的核心知识点,包括 Java8 的新特性、Java 并发编程以及 Java NIO 技术。学习这些内容对于理解现代 Java 开发至关重要,特别是对于希望提升自己技能水平和...
Java-JUC-多线程进阶 Java-JUC-多线程进阶resources是 Java 并发编程的高级课程,涵盖了 Java 中的并发编程概念、线程安全、锁机制、集合类、线程池、函数式接口、Stream流式计算等多个方面。 什么是JUC JUC...
java高级技术JUC高并发编程教程2021(1.5G) 〖课程介绍〗: java高级技术JUC高并发编程教程2021(1.5G) 〖课程目录〗: 01-JUC高并发编程-课程介绍.mp4 02-JUC高并发编程-JUC概述和进程线程概念(1).mp4 03-JUC...
Java并发包(JUC)是Java 5引入的一个重要特性,主要包含了`java.util.concurrent`包。这个包的设计目的是为了简化并发编程,提供一系列高效的工具类,使得开发者在编写多线程程序时能更加便捷和安全。`JUC并发包开发...