
Java并发
Java并发
Xzzz2020
个人博客地址:https://xzzz2020.gitee.io/,可以收藏一下,会第一时间发布文章
展开
-
【详解】Executors框架之CompleableFuture
使用Future获得异步执行结果时,要么调用阻塞方法get(),要么轮询看isDone()是否为true,这两种方法都不是很好,因为主线程也会被迫等待。从Java 8开始引入了CompletableFuture,它针对Future做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。优势如下:可以利用结果进行级联的执行会自动回调给调用者执行一批任务时,可以按照任务执行的顺序,获得结果可以并行的获取结果,只拿最先获取的结果级联的执行原创 2020-05-13 11:50:58 · 1193 阅读 · 0 评论 -
【详解】Executors框架之CompletionService
Future的缺点虽然Future可以异步的执行任务,但是还是有很多缺点:没有办法回调,需要手动的调用执行一组任务需要等待所有的任务执行完CompletionService简介CompletionService的实现目标是任务先完成可优先获取到,即结果按照完成先后顺序排序。ExecutorCompletionService类,该类只有三个成员变量:public class ExecutorCompletionService<V> implements CompletionSer原创 2020-05-11 17:33:30 · 400 阅读 · 0 评论 -
【详解】Executors框架之Future&Callable
简介这个思想来源于Future设计模式:https://blog.youkuaiyun.com/qq_43040688/article/details/105868293public interface Callable<V> { V call() throws Exception;}可以看到,这是一个泛型接口,该接口声明了一个名称为call()的方法,同时这个方法可以有返回值V,也可以抛出异常。call()方法返回的类型就是传递进来的V类型。那么怎么使用Callable呢?一般情况原创 2020-05-11 17:01:11 · 322 阅读 · 0 评论 -
【详解】Executors框架之ExecutorService
简介我们之前使用线程的时候都是使用new Thread来进行线程的创建,但是这样会有一些问题。如:a. 每次new Thread新建对象性能差。b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。c. 缺乏更多功能,如定时执行、定期执行、线程中断。相比new Thread,Java提供的四种线程池的好处在于:a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。b. 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。原创 2020-05-11 15:01:31 · 170 阅读 · 0 评论 -
【详解】Executors框架之Executors
简介Java通过Executors提供五种线程池,分别为:newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保原创 2020-05-11 10:22:34 · 862 阅读 · 0 评论 -
【详解】Executors框架之ThreadPoolExecutor
目录线程池创建的参数测试测试代码结果结论:线程池的阻塞队列的选择?拒绝策略关闭shutdownshutdownNow守护线程线程池创建的参数public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit原创 2020-05-10 21:32:07 · 432 阅读 · 0 评论 -
【详解】JUC之Phaser(移相器)
目录简介简单的使用重复使用的例子动态减少API重要API注册到达不再等待机制监控子线程任务强制关闭调试API获取阶段数获取注册的数获得到达和未到达的数目总结简介java7中引入了一种新的可重复使用的同步屏障,称为移相器Phaser。Phaser拥有与CyclicBarrier和CountDownLatch类似的功劳.但是这个类提供了更加灵活的应用。CountDownLatch和CyclicBarrier都是只适用于固定数量的参与者。移相器适用于可变数目的屏障,在这个意义上,可以在任何时间注册新的参与者原创 2020-05-10 15:51:11 · 1035 阅读 · 0 评论 -
【详解】JUC之ForkJoin框架
简介从JDK1.7开始,Java提供ForkJoin框架用于并行执行任务,它的思想就是:将一个大任务分割成若干小任务,最终汇总每个小任务的结果得到这个大任务的结果。整个流程需要三个类完成:1、ForkJoinPool既然任务是被逐渐的细化的,那就需要把这些任务存在一个池子里面,这个池子就是ForkJoinPool。它与其它的ExecutorService区别主要在于它使用“工作窃取“,那什么是工作窃取呢?一个大任务会被划分成无数个小任务,这些任务被分配到不同的队列,这些队列有些干活干的块,有些干原创 2020-05-10 10:52:00 · 221 阅读 · 0 评论 -
【详解】Java高并发三种锁的比较
引入在Java高并发场景下,主要使用是三种锁synchronized、StampedLock、Lock比较synchronizedStampedLockLock是JVM的的内置锁,每个JDK版本都会优化是一个Java类,可以更好的扩展是一个Java类,可以更好的扩展都是悲观锁提供了写的乐观锁都是悲观锁,但是提供了自旋锁,或者不阻塞的获取锁性能一般,因为有一个从用户态到内核态的过程性能最好,可以代替读写锁性能十分不稳定,在复杂的读写环境下,性能十分差不原创 2020-05-10 09:53:40 · 1032 阅读 · 0 评论 -
【详解】JUC之StampedLock
引出如果我们深入分析ReadWriteLock,会发现它有个潜在的问题:如果有线程正在读,写线程需要等待读线程释放锁后才能获取写锁,即读的过程中不允许写,这是一种悲观的读锁。要进一步提升并发执行效率,Java 8引入了新的读写锁:StampedLock。StampedLock和ReadWriteLock相比,改进之处在于:读的过程中也允许获取写锁后写入!这样一来,我们读的数据就可能不一致,所以,需要一点额外的代码来判断读的过程中是否有写入,这种读锁是一种乐观锁。乐观锁的意思就是乐观地估计读的过程中大原创 2020-05-10 09:25:44 · 222 阅读 · 0 评论 -
【详解】JUC之Condition
目录引出初步使用问题解答第一个问题第二个问题第三个问题wait和await的区别等待队列总结利用Condition实现生产者和消费者与 ReentrantLock的关系总结引出在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了。配合Object的wait()、notify()系列方法可以实现等待/通知模式。Condition接口也提供了类似Obj...原创 2020-05-07 18:27:43 · 1356 阅读 · 1 评论 -
【详解】JUC之读写锁
引出读写锁的设计主要参考读写锁的设计模式:https://blog.youkuaiyun.com/qq_43040688/article/details/105857920使用public class ReadWriteLockTest { private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock...原创 2020-05-07 16:25:22 · 391 阅读 · 0 评论 -
【详解】JUC之ReentrantLock
简介当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题。java提供了两种方式来加锁:一种是关键字:synchronized,一种是concurrent包下的lock锁。synchronized是java底层支持的,而concurrent包则是jdk实现。公平锁和非公平锁当有线程竞争锁时,当前线程会首先尝试获得锁而不是在队列中进行排队等候,...原创 2020-05-07 16:24:58 · 325 阅读 · 0 评论 -
【详解】JUC之Semaphore
简介Semaphore是一种在多线程环境下使用的设施,该设施负责协调各个线程,以保证它们能够正确、合理的使用公共资源的设施,也是操作系统中用于控制进程同步互斥的量。Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。它相当于给线程规定一个量从而控制允许活动的线程数。Semaphore用于限制可以访问某些资源(物理或逻辑的)的线程数目,他维护了一个许可证集合,有多...原创 2020-05-06 20:39:07 · 229 阅读 · 0 评论 -
【详解】JUC之Exchanger
简介用于两个工作线程之间交换数据的封装工具类简单说就是一个线程在完成一定的事务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程,直到第二个线程拿着数据到来时才能彼此交换对应数据Exchanger<V> 泛型类型,其中 V 表示可交换的数据类型简单的应用public class ExchangerTest { public static vo...原创 2020-05-06 18:32:08 · 282 阅读 · 0 评论 -
【详解】JUC之CyclicBarrier
引出栅栏类似于闭锁,它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于,所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而栅栏用于等待其他线程。CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而...原创 2020-05-06 17:40:48 · 280 阅读 · 0 评论 -
【详解】JUC之CountDownLatch
目录一、引入二、分析三、使用场景一四、使用场景二五、API使用六、给离散的平行任务增加逻辑层次关系一、引入countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。是通过一个计数器来实现的,计数器的初始值是线程的数量或者任务的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。Count...原创 2020-05-05 19:01:47 · 411 阅读 · 0 评论 -
【详解】Java高并发之UnSafe类
Unsafe类是在sun.misc包下,不属于Java标准。但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty、Cassandra、Hadoop、Kafka等。Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。Unsafe类使Java拥有了像C语言的指针一样操作内存空间的能力,同时也带来了指针的问题。过度的...原创 2020-05-05 16:03:41 · 496 阅读 · 0 评论 -
比较几种自增操作时间复杂度
比较几种Counter的自增操作时间编写一个没有做任何处理的自增static class StupidCounter implements Counter{ private long counter = 0; @Override public void increment() { counter++; } @Override ...原创 2020-05-05 16:02:59 · 320 阅读 · 0 评论 -
【详解】Java并发之AtomicxxxFieldUpdater
引出由于原子性的类型是后期引出的,但是想让原来已经写好的属性也具有原子性,就可以利用这个类AtomicXXXFieldUpdater主要包括以下几个:AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater。要求字段必须是volatile类型的,在线程之间共享变量时保证立即可见字段的描述类型...原创 2020-05-04 21:00:53 · 222 阅读 · 0 评论 -
【详解】Java高并发值AtomicReference
AtomicReference提供了引用变量的读写原子性操作。提供了如下的方法:compareAndSet(V expect, V update)getAndSet(V newValue)lazySet(V newValue)set(V newValue)get()举例public class AtomicReferenceTest { private static...原创 2020-05-04 16:02:57 · 658 阅读 · 0 评论 -
【详解】Java高并发原子类型之AtomicBoolean
分析在高并发条件下,如果都需要对flag进行修改,就会破坏其原子性观察下面代码public class AtomicBooleanTest { private static volatile Boolean flag = true; public static void main(String[] args) { for (int i = 0; i &...原创 2020-05-04 15:27:25 · 506 阅读 · 0 评论 -
【详解】Java高并发之CAS
目录一、CAS机制二、举例三、CAS的缺点四、利用CAS实现TryLock一、CAS机制CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。从思想上来说,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观...原创 2020-05-04 14:53:30 · 766 阅读 · 0 评论 -
【详解】Java高并发原子类型之AtomicInteger
【详解】Java高并发原子类型之AtomicInteget原创 2020-05-04 14:56:26 · 466 阅读 · 0 评论 -
【详解】Java多线程之Active Object设计模式
Active是主动的意思,因此ActiveObject就是主动对象的意思。所谓主动一般指有自己特有的线程,举例来说,java.lang.Thread类的实例就是一种主动对象。不过,在Active Object模式中出厂的主动对象可不仅仅有自己特有的线程,它同时还具备可以从外部接收和处理异步消息并根据需要返回处理结果的特征。Active Object模式中的主动对象会通过自己特有的线程在合适的时...原创 2020-05-03 11:08:18 · 1203 阅读 · 0 评论 -
【详解】Java多线程之worker设计模式
分析Master-Worker模式是常用的并行设计模式。核心思想是,系统由两个角色组成,Master和WorkerMaster负责接收和分配任务Worker负责处理子任务任务处理过程中,Master还负责监督任务进展和Worker的健康状态;Master将接收Client提交的任务,并将任务的进展汇总反馈给Client。基本框架主要需要设计一个队列,开启多个线程然后任务就按照队...原创 2020-05-02 20:57:08 · 1141 阅读 · 0 评论 -
【详解】Java多线程之两个阶段终止设计模式
分析Two-Phase Termination Pattern,指的就是当希望结束一个线程的时候,送出一个终止请求,但是不会马上停止,做一些刷新工作。进入“终止处理中”,在该状态下,不会进行该线程日常工作任务的操作,而是进行一些终止操作。这个方式所考虑的因素如下:1,必须要考虑到使得该线程能够安全的结束,Thread中的stop会有问题的,因为它会不管线程执行到哪里,都会马上停止,不能保...原创 2020-05-02 20:11:07 · 259 阅读 · 0 评论 -
【详解】Java多线程之Thread-Per-Message设计模式
分析每个消息一个线程。message可以理解为命令,请求。为每一个请求新分配一个线程,由这个线程来执行处理。Thread-Per-Message模式中,请求的委托端和请求的执行端是不同的线程,请求的委托端会告诉请求的执行端线程:这项工作就交给你了编码public class MessageHandler { private final static Random RANDOM ...原创 2020-05-02 17:03:03 · 305 阅读 · 0 评论 -
【详解】Java多线程之Count down设计模式
分析Count-Down设计模式其实也叫做Latch(阀门)设计模式。当若干个线程并发执行完某个特定的任务,然后等到所有的子任务都执行结束之后再统一汇总。JDK包中的实现public class JDKCountDown { private static final Random RANDOM = new Random(System.currentTimeMillis());...原创 2020-05-02 16:45:02 · 784 阅读 · 0 评论 -
【详解】生产者消费者设计模式
分析多个线程负责生产消息,多个线程负责发送消息生产和发送消息都需要加锁如果没有消息需要发送,则进入线程等待编码需要注意:在线程调用一些方法时,不要使用try…catch…,而是将异常抛出,在线程处理逻辑统一处理。否则,会造成线程无法关闭等异常操作public class MessageQueue { private final LinkedList<Messa...原创 2020-05-02 16:27:14 · 348 阅读 · 0 评论 -
【详解】多线程之Balking设计模式
分析介绍定期将当前数据内容写入文件中,比如文本工具的自动保存功能,定期的将数据保存到文件中。当写入的内容和上次的内容完全相同时,再向文件写入就多余了,所以就不再执行写入操作。所以这个程序就是以 数据内容不同 作为守护条件,如果数据内容相同,就不执行写入操作,直接返回(balk)作用当多个线程执行同一个操作时,如果已经执行过了,就可以不用再执行,提高程序的效率编码实现一个线...原创 2020-05-02 15:20:39 · 284 阅读 · 0 评论 -
【详解】上下文设计模式
分析线程在执行过程中可能分了多个阶段后一个方法可能需要用到前一个阶段的结果通过设置一个上下文,每执行一个方法,将结果放入到上下文中,下一个方法的调用时,会调取上下文中的结果继续执行这个上下文是在一个线程内部是单例的上下文实现先设计一个上下文,负责在线程执行的过程中传递结果模拟两个方法,第一个方法从数据库拿名字,第二个方法根据第一个方法拿出的名字返回身份证号设计线程的执行方法,...原创 2020-05-02 11:51:40 · 2746 阅读 · 0 评论 -
【详解】ThreadLocal(线程保险箱)
分析threadlocal在线程间是隔离的,不共享,用于存储线程的变量即使多个线程使用同一个ThreadLocal,也只能访问自己的属性一个简单的例子线程1和线程2分别从同一个ThreadLocal中存取变量主线程没有存变量,也在获取可以发现,每个线程获取的都是自己存的如果没有存,则返回默认的,默认是空public class ThreadLocalComplexTest {...原创 2020-05-02 10:52:06 · 183 阅读 · 0 评论 -
【详解】Java并发之确保挂起设计模式
分析在Tomcat中的例子Request -> Tomcat httpServer -> doing.................Request -> Tomcat httpServer -> Queue wait -> doing需求 一个线程正在做一个非常关键的任务,这时,有一个其他的线程让当前线程做其他的事情,当前线程只有完成当前的任务才...原创 2020-05-02 10:16:45 · 251 阅读 · 0 评论 -
【详解】Java并发之Fature设计模式
分析Future模式的核心在于:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑。Future模式有点类似于商品订单。在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直持续等待直到这个答复收到之后再去做别的事情,但如果利用Future模式,其调用...原创 2020-04-30 20:44:47 · 1232 阅读 · 0 评论 -
【详解】Java多线程之不可变对象设计模式
分析这是一种无锁的设计模式,因为不可变对象没有任何机会去修改这个对象的属性或者引用类型需要有两个概念不可变对象一定是线程安全的可变对象不一定是不安全的创建不可见对象的原则:1)所有成员变量必须是private2)最好同时用final修饰(非必须)3)不提供能够修改原有对象状态的方法最常见的方式是不提供setter方法如果提供修改方法,需要新创建一个对象,并在新创建的...原创 2020-04-30 19:35:12 · 266 阅读 · 0 评论 -
【详解】Java并发之读写锁分离设计模式
分析读写锁最重要的需求是:多个线程如果都是在读取数据,如果依然采用加锁的方式,会严重影响效率。所以需要对读写锁进行分离这种方式适用于:读取的操作比较多需要考虑以下冲突,否则会出现数据不一致的情况冲突策略读 — 读并行化读 — 写串行化写 — 写串行化读写锁的设计思想就是避免冲突编码首先设计的读写锁在获取读锁的时候,需要看看是否存在正在写的...原创 2020-04-30 13:16:11 · 320 阅读 · 0 评论 -
【详解】Java并发之单线程执行设计模式
问题引出该问题出现分为三个角色门:相当于共享资源用户:相当于一个线程客户端:负责启动多个线程通过这个门资源在线程使用资源的时候,做了一个检查,检查此时使用资源的名字和地址是否相同/** * 门,相当于共享资源 */public class Gate { private int counter = 0; private String name = "Nobody...原创 2020-04-30 11:22:21 · 491 阅读 · 0 评论 -
【详解】Java多线程中的观察者模式
观察者模式介绍定义一个观察者,观察一个主题subject/** * 一个观察者的抽象类 * 具体当状态发生变化进行的操作交给子类实现 */public abstract class Observer { protected Subject subject; public Observer(Subject subject) { this.subject...原创 2020-04-29 11:58:11 · 1136 阅读 · 0 评论 -
【详解】Java多线程之内存模型三大特性
目录一、数据不一致的问题二、解决方法一、数据不一致的问题CPU运行速度比较快,每次去内存读取数据就比较耗时所以,CPU与内存之间会存在一个高速缓存来提高CPU的效率这个高速缓存存放着从内存中读取的数据当一个线程仅仅对数据是读取的操作,Java会认为该线程不需要刷新缓存。当有另一个线程,对数据进行修改时,第一个线程不可见,出现了数据不一致的问题JMM模型代码演示public c...原创 2020-04-28 21:24:26 · 614 阅读 · 0 评论