Java并发编程(十四)-CompletableFuture
参考文献
Java8实战
CompletableFuture原理与实践-外卖商家端API的异步化
Future
通常只需要使用将耗时的操作封装在一个Callable对象中,再将它提交给ExecutorService
1234567891011121314151617public class FutureTest { public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); Future<Double> future = executor.submit(new Callable<Double>() { @Override public Double call() throws Exception { return doSomeLongComputation(); ...
Java并发编程(九)-并发工具类简介
参考文献
Java并发编程的艺术
CountDownLatch
CyclicBarrier
Java并发编程入门(十五)CyclicBarrier应用场景
并发工具类
提供了比synchronized更加高级的各种同步结构,包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作,比如利用Semaphore作为资源控制器,限制同时进行工作的线程数量.
各种线程安全的容器,比如最常见的ConcurrentHashMap、有序的ConcunrrentSkipListMap,或者通过类似快照机制,实现线程安全的动态数组CopyOnWriteArrayList等.
各种并发队列实现,如各种BlockedQueue实现,比较典型的ArrayBlockingQueue、SynchorousQueue或针对特定场景的PriorityBlockingQueue等.
强大的Executor框架,可以创建各种不同类型的线程池,调度任务运行等,绝大部分情况下,不再需要自己从头实现线程池和任务调度器.
CountDownLatch(等待多个线程 ...
Java并发编程(七)-Java内存模型(JMM)
参考文献
<<Java并发编程艺术>>
<<深入理解Java虚拟机-JVM高级特性与最佳实践>>
JSR 133 (Java Memory Model) FAQ
The Java Memory Model
【死磕Java并发】-----Java内存模型之happens-before
The JSR-133 Cookbook for Compiler Writers
Java内存模型(JMM)
The Java memory model describes how threads in the Java programming language interact through memory. Together with the description of single-threaded execution of code, the memory model provides the semantics of the Java programming language. --Wikipedia
Java内存模型描述了Java编程 ...
Java并发编程(六)-Java并发机制的底层实现原理-原子操作
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
原子操作的实现原理
在Java中可以通过锁和循环CAS的方式来实现原子操作;
使用循环CAS实现原子操作
JVM中CAS操作是利用处理器提供的CMPXCHG指令实现的.自旋CAS实现的基本思路就是循环进行CAS操作直到成功为止.
1234for(;;){ int i = atomicI.get(); boolean sunc= atomicI.compareAndSet(i,i++);}
CAS实现原子操作的三大问题
ABA问题
因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时就会发现它的值没有发生变化,但是实际上变化了.
ABA问题的解决思路就是用版本号.在变量前面追加版本号,每次变量更新的时候把版本号加1,那么由原来的A->B->A变成了1A->2B->3A.
从JDK5开始 ...
Java并发编程五-Java并发机制的底层实现原理-synchronized
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
http://www.itabin.com/synchronized-lock/
引言
Java编程语言提供了多种用于线程通信的机制.这些方法中最基础的就是同步(synchronization),它是使用监视器(monitor)实现的.Java中每个对象都与一个线程可以锁定或解锁的监视器相关联.在任何时刻,只有一个线程可以持有某个监视器上的锁.任何其他试图锁定该监视器线程都将阻塞,直到它们可以获得该监视器上的锁.
线程T可以多次锁定某个特定的监视器,而每个解锁操作都会抵消一次锁定操作的效果.(可重入锁)
synchronized
synchronized语句是对对象的引用,即基于对象实现,然后它试图执行在该对象的监视器上的锁定动作,并且在锁定动作成功完成之前,不会执行下一步动作.在锁定动作执行之后,synchronized语句体被执行.如果该语句体执行结束,无论是正常结束还是异常结束,都会在相同的监视器上执行解锁动作.
syn ...
Java并发编程(四)-Java并发机制的底层实现原理-volatile
参考文献
<<Java并发编程艺术>>
<<Java语言规范-基于Java SE 8>>
CPU高速缓存行与内存关系 及并发MESI 协议
[死磕 Java 并发] — Java内存模型之分析volatile
volatile
CPU术语
术语
英文
描述
内存屏障
memory barrier
是一组处理器指令,用于实现对内存操作的顺序限制
缓存行
cache line
缓存中可以分配的最小存储单位.处理器填写缓存行时会加载整个缓存行,需要使用多个主内存读周期
原子操作
atomic operations
不可中断的一个或一系列操作
缓存行填充
cache line fill
当处理器识别到从内存中读取操作数是可缓存的,处理器读取整个缓存行到适当的缓存(L1,L2,L3的或所有)
缓存命中
cache hit
如果进行高速缓存行填充操作的内存位置仍然是下次处理器访问的地址时,处理器从缓存中读取操作数,而不是内存读取
写命中
write hit
当处理器将操作数写回到一个内存缓存的区域时,它首先会检 ...
Java并发编程(三)-锁
参考文献
锁的简单应用
图解Java中那18 把锁
<<Java并发编程艺术>>
Synchronization
锁
锁的分类
分类标准把锁分为以下 7 大类别
偏向锁/轻量级锁/重量级锁;
可重入锁/非可重入锁;
共享锁/独占锁;
公平锁/非公平锁;
悲观锁/乐观锁;
自旋锁/非自旋锁;
可中断锁/不可中断锁.
使用锁的目的
锁是用来控制多个线程访问共享资源的方式.一个锁能够防止多个线程同时访问共享资源.
死锁
产生死锁的原因
当前线程拥有其他线程需要的资源,当前线程等待其他线程已拥有的资源,同时不放弃自己拥有的资源;
如何预防死锁
只有以下这四个条件都发生时才会出现死锁:
互斥:共享资源X和Y只能被一个线程占用;
占有且等待: 线程T1已取得共享资源X,在等待共享资源Y的时候,不释放共享资源X;
不可抢占: 其他线程不能强行抢占线程T1占有的资源;
循环等待: 线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,就是循环等待.
即破坏其中一个,就可以成功避免死锁的发生
对于"占用且等待"这个条件 ...
Java并发编程(二)-线程
参考文献
<<Java并发编程艺术>>
<<深入理解Java虚拟机-JVM高级特性与最佳实践>>
线程
线程的创建和运行
直接使用Thread
1Thread t= new Thread(()->{}).start();
Runnable配合Thread
123Runnable runnable = () -> log.debug("hellow");Thread t = new Thread(runnable);t.start;
实现Callable接口通过FutureTask包装器来创建Thread线程;
12345678// FutureTask能接收Callable类型的参数,用来处理返回结果FutureTask<String> task = new FutureTask<>(()->{ log.debug("hello"); return "demo";})new Thr ...
Java并发编程(一)-并发相关知识点
参考文献
并发与并行的区别是什么?
<<Java并发编程实战>>
极客时间:Java并发编程实战
必懂系列!Java并发面试题
【对线面试官】多线程基础
<<Java并发编程艺术>>
Java 并发 - 理论基础
ON JAVA 进阶卷
进程之间通信的方式
RPC/HTTP/信号量/消息队列/管道/socket
并发编程中核心的问题
分工: 如何高效地拆解任务并分配给线程
Java SDK Fork/Join框架就是一种分工模式
同步: 指线程之间如何协作
CountDownLatch就是一种典型的同步方式
互斥: 保证同一时刻只允许一个线程访问共享资源
可重入锁则是一种互斥手段
同步
并发编程领域的同步主要指线程之间的协作,指一个线程执行完了一个任务,如何通知后续任务的线程开工
工作中遇到的线程协作问题,基本上都可以描述为这样一个问题:
当某个条件不满足时,线程需要等待;
当某个条件满足时,线程需要被唤醒执行;
解决协作问题的核心技术是"管程"
互斥
实现互斥的核心技术是锁 ...
Java并发编程(十)-ThreadLocal
参考文献
【对线面试官】ThreadLocal
JAVA并发编程实战
Spring 4.3: Using a TaskDecorator to copy MDC data to @Async threads
从ThreadLocal到InheritThreadLocal再到阿里的TransmittableThreadLocal,吊打面试官
ThreadLocal
它运行你将每个线程与持有数值的对象关联在一起.ThreadLocal提供了get与set访问器,为每个使用它的线程维护一份单独的拷贝.所以get总是返回由当前执行线程通过set设置的最新值.
一种解决多线程环境下成员变量的问题的方案,但是与线程同步无关.其思路是为每一个线程创建一个单独的变量副本,从而每个线程都可以独立地改变自己所拥有的变量副本,而不会影响其他线程所对应的副本
线程本地(ThreadLocal)变量通常用与基于可变的单体(Singleton)或全局变量的设计中,出现(不正确的)共享.
比如说,一个单线程的应用程序可能会维护一个全局的数据连接,这个Connection在启动时就已经被初始化了.这 ...