
多线程
flydean程序那些事
懂程序更懂你!微信公众号:程序那些事 个人主页:www.flydean.com 最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在程序那些事!
展开
-
并发和Read-copy update(RCU)
在上一篇文章中的并发和ABA问题的介绍中,我们提到了要解决ABA中的memory reclamation问题,有一个办法就是使用RCU。今天本文将会深入的探讨一下RCU是什么,RCU和COW(Copy-On-Write)之间的关系。RCU(Read-copy update)是一种同步机制,并在2002年被加入了Linux内核中。它的优点就是可以在更新的过程中,运行多个reader进行读原创 2020-06-04 06:20:48 · 13521 阅读 · 7 评论 -
ABA问题的本质及其解决办法
CAS的全称是compare and swap,它是java同步类的基础,java.util.concurrent中的同步类基本上都是使用CAS来实现其原子性的。CAS的原理其实很简单,为了保证在多线程环境下我们的更新是符合预期的,或者说一个线程在更新某个对象的时候,没有其他的线程对该对象进行修改。在线程更新某个对象(或值)之前,先保存更新前的值,然后在实际更新的时候传入之前保存的值,进行比较,如果一致的话就进行更新,否则失败。原创 2020-06-01 07:00:17 · 8568 阅读 · 5 评论 -
怎么break java8 stream的foreach
文章目录简介使用Spliterator自定义forEach方法总结怎么break java8 stream的foreach简介我们通常需要在java stream中遍历处理里面的数据,其中foreach是最最常用的方法。但是有时候我们并不想处理完所有的数据,或者有时候Stream可能非常的长,或者根本就是无限的。一种方法是先filter出我们需要处理的数据,然后再foreach遍历。那...原创 2020-04-26 07:45:34 · 11309 阅读 · 0 评论 -
java 8 stream中的Spliterator简介
文章目录简介tryAdvancetrySplitestimateSizecharacteristics举个例子总结java 8 stream中的Spliterator简介简介Spliterator是在java 8引入的一个接口,它通常和stream一起使用,用来遍历和分割序列。只要用到stream的地方都需要Spliterator,比如List,Collection,IO channel等...原创 2020-04-26 07:40:44 · 11331 阅读 · 0 评论 -
java stream中Collectors的用法
在java stream中,我们通常需要将处理后的stream转换成集合类,这个时候就需要用到stream.collect方法。collect方法需要传入一个Collector类型,要实现Collector还是很麻烦的,需要实现好几个接口。于是java提供了更简单的Collectors工具类来方便我们构建Collector。下面我们将会具体讲解Collectors的用法原创 2020-04-24 07:46:58 · 13634 阅读 · 0 评论 -
java关于throw Exception的一个小秘密
文章目录简介throw小诀窍总结java关于throw Exception的一个小秘密简介之前的文章我们讲到,在stream中处理异常,需要将checked exception转换为unchecked exception来处理。我们是这样做的: static <T> Consumer<T> consumerWrapper( Throw...原创 2020-04-24 07:42:37 · 10223 阅读 · 2 评论 -
java 8 lambda表达式中的异常处理
文章目录简介处理Unchecked Exception处理checked Exception总结java 8 lambda表达式中的异常处理简介java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Interf...原创 2020-04-23 06:59:08 · 10564 阅读 · 1 评论 -
java 8 Stream中操作类型和peek的使用
文章目录简介中间操作和终止操作peek结论java 8 Stream中操作类型和peek的使用简介java 8 stream作为流式操作有两种操作类型,中间操作和终止操作。这两种有什么区别呢?我们看一个peek的例子:Stream<String> stream = Stream.of("one", "two", "three","four"); stream....原创 2020-04-23 06:54:41 · 11252 阅读 · 0 评论 -
java并发Exchanger的使用
文章目录简介类定义类继承构造函数两个主要方法具体的例子结语简介Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的。这里主要是两个线程之间交换持有的对象。当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法。两个线程都调用exchange方法之后,传入的参数就会交换。类定义public class...原创 2020-04-21 07:13:50 · 9356 阅读 · 0 评论 -
java中functional interface的分类和使用
文章目录简介Functional InterfaceFunction:一个参数一个返回值BiFunction:接收两个参数,一个返回值Supplier:无参的FunctionConsumer:接收一个参数,不返回值Predicate:接收一个参数,返回booleanOperator:接收和返回同样的类型总结简介java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的f...原创 2020-04-20 11:13:13 · 9994 阅读 · 0 评论 -
java 8 Streams简介
文章目录简介Functional InterfaceFunction:一个参数一个返回值BiFunction:接收两个参数,一个返回值Supplier:无参的FunctionConsumer:接收一个参数,不返回值Predicate:接收一个参数,返回booleanOperator:接收和返回同样的类型总结简介java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的f...原创 2020-04-20 11:07:46 · 9761 阅读 · 0 评论 -
java内存模型(JMM)和happens-before
文章目录重排序Happens-Before安全发布初始化安全性java内存模型(JMM)和happens-before我们知道java程序是运行在JVM中的,而JVM就是构建在内存上的虚拟机,那么内存模型JMM是做什么用的呢?我们考虑一个简单的赋值问题:int a=100;JMM考虑的就是什么情况下读取变量a的线程可以看到值为100。看起来这是一个很简单的问题,赋值之后不就可以读到值了...原创 2020-04-16 07:17:53 · 9543 阅读 · 0 评论 -
非阻塞算法(Lock-Free)的实现
文章目录非阻塞的栈非阻塞的链表非阻塞算法(Lock-Free)的实现上篇文章我们讲到了使用锁会带来的各种缺点,本文将会讲解如何使用非阻塞算法。非阻塞算法一般会使用CAS来协调线程的操作。虽然非阻塞算法有诸多优点,但是在实现上要比基于锁的算法更加繁琐和负责。本文将会介绍两个是用非阻塞算法实现的数据结构。非阻塞的栈我们先使用CAS来构建几个非阻塞的栈。栈是最简单的链式结构,其本质是一个链表...原创 2020-04-15 10:24:17 · 9517 阅读 · 0 评论 -
非阻塞同步机制和CAS
文章目录什么是非阻塞同步悲观锁和乐观锁CAS非阻塞同步机制和CAS我们知道在java 5之前同步是通过Synchronized关键字来实现的,在java 5之后,java.util.concurrent包里面添加了很多性能更加强大的同步类。这些强大的类中很多都实现了非阻塞的同步机制从而帮助其提升性能。什么是非阻塞同步非阻塞同步的意思是多个线程在竞争相同的数据时候不会发生阻塞,从而能够在更加...原创 2020-04-15 10:17:49 · 9475 阅读 · 0 评论 -
同步类的基础AbstractQueuedSynchronizer(AQS)
同步类的基础AbstractQueuedSynchronizer(AQS)我们之前介绍了很多同步类,比如ReentrantLock,Semaphore, CountDownLatch, ReentrantReadWriteLock,FutureTask等。AQS封装了实现同步器时设计的大量细节问题。他提供了FIFO的wait queues并且提供了一个int型的state表示当前的状态。根据...原创 2020-04-14 12:07:39 · 9384 阅读 · 0 评论 -
由于不当的执行顺序导致的死锁
为了保证线程的安全,我们引入了加锁机制,但是如果不加限制的使用加锁,就有可能会导致顺序死锁(Lock-Ordering Deadlock)。上篇文章我们也提到了在线程词中因为资源的不足而导致的资源死锁(Resource Deadlock)。本文将会讨论一下顺序死锁的问题。我们来讨论一个经常存在的账户转账的问题。账户A要转账给账户B。为了保证在转账的过程中A和B不被其他的线程意外的操作,我们需要...原创 2020-04-11 08:58:03 · 9822 阅读 · 0 评论 -
java中有界队列的饱和策略(reject policy)
文章目录AbortPolicyDiscardPolicyDiscardOldestPolicyCallerRunsPolicy使用Semaphorejava中有界队列的饱和策略(reject policy)我们在使用ExecutorService的时候知道,在ExecutorService中有个一个Queue来保存提交的任务,通过不同的构造函数,我们可以创建无界的队列(ExecutorServ...原创 2020-04-10 10:17:55 · 10352 阅读 · 0 评论 -
万万没想到,线程居然被饿死了!
我们的线程被饿死了我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。那么线程池使用不当可不可能产生死锁呢?我们知道死锁是循环争夺资源而产生的。线程池中的线程也是资源的一种,那么如果对线程池中的线程进行争夺的话也是可能产生死锁的。在单个线程的线程池中,如果一个正在执行的线程中,使用该线程池再去提交第二个任务,因为线程池中的线程只有一个,那么第二个任务将会等待第一个任务的执行完成...原创 2020-04-09 10:11:44 · 10278 阅读 · 0 评论 -
使用ExecutorService来停止线程服务
文章目录使用shutdown使用shutdownNow使用ExecutorService来停止线程服务之前的文章中我们提到了ExecutorService可以使用shutdown和shutdownNow来关闭。这两种关闭的区别在于各自的安全性和响应性。shutdownNow强行关闭速度更快,但是风险也更大,因为任务可能正在执行的过程中被结束了。而shutdown正常关闭虽然速度比较慢,但是却...原创 2020-04-08 09:57:04 · 11265 阅读 · 0 评论 -
java中CompletionService的使用
java中CompletionService的使用之前的文章中我们讲到了ExecutorService,通过ExecutorService我们可以提交一个个的task,并且返回Future,然后通过调用Future.get方法来返回任务的执行结果。这种方式虽然有效,但是需要保存每个返回的Future值,还是比较麻烦的,幸好ExecutorService提供了一个invokeAll的方法,来保存...原创 2020-04-03 09:25:05 · 9884 阅读 · 0 评论 -
在java中构建高效的结果缓存
文章目录使用HashMap使用ConcurrentHashMapFutureTask在java中构建高效的结果缓存缓存是现代应用服务器中非常常用的组件。除了第三方缓存以外,我们通常也需要在java中构建内部使用的缓存。那么怎么才能构建一个高效的缓存呢? 本文将会一步步的进行揭秘。使用HashMap缓存通常的用法就是构建一个内存中使用的Map,在做一个长时间的操作比如计算之前,先在Map中查...原创 2020-04-02 09:20:29 · 9487 阅读 · 2 评论 -
java中使用Semaphore构建阻塞对象池
java中使用Semaphore构建阻塞对象池Semaphore是java 5中引入的概念,叫做计数信号量。主要用来控制同时访问某个特定资源的访问数量或者执行某个操作的数量。Semaphore中定义了一组虚拟的permits,通过获取和释放这些permits,Semaphore可以控制资源的个数。Semaphore的这个特性可以用来构造资源池,比如数据库连接池等。Semaphore有两个构...原创 2020-04-01 09:29:32 · 9444 阅读 · 0 评论 -
Phaser都不懂,还学什么多线程
前面的文章中我们讲到了CyclicBarrier、CountDownLatch的使用,这里再回顾一下CountDownLatch主要用在一个线程等待多个线程执行完毕的情况,而CyclicBarrier用在多个线程互相等待执行完毕的情况。Phaser是java 7 引入的新的并发API。他引入了新的Phaser的概念,我们可以将其看成一个一个的阶段,每个阶段都有需要执行的线程任务,任务执行完毕就进...原创 2020-03-31 09:08:30 · 9295 阅读 · 0 评论 -
关于CompletableFuture的一切,看这篇文章就够了
文章目录CompletableFuture作为Future使用异步执行code组合FuturesthenApply() 和 thenCompose()的区别并行执行任务异常处理java中CompletableFuture的使用之前的文章中,我们讲解了Future, 本文我们将会继续讲解java 8中引入的CompletableFuture的用法。CompletableFuture首先是一个F...原创 2020-03-30 09:20:22 · 12358 阅读 · 4 评论 -
java中FutureTask的使用
文章目录FutureTask简介Callable和Runnable的转换以Runnable运行java中FutureTask的使用FutureTask简介FutureTask是java 5引入的一个类,从名字可以看出来FutureTask既是一个Future,又是一个Task。我们看下FutureTask的定义:public class FutureTask<V> imple...原创 2020-03-28 16:12:28 · 11164 阅读 · 0 评论 -
java中ThreadLocalRandom的使用
java中ThreadLocalRandom的使用在java中我们通常会需要使用到java.util.Random来便利的生产随机数。但是Random是线程安全的,如果要在线程环境中的话就有可能产生性能瓶颈。我们以Random中常用的nextInt方法为例来具体看一下: public int nextInt() { return next(32); }nex...原创 2020-03-27 09:18:35 · 9883 阅读 · 0 评论 -
在java中使用JMH(Java Microbenchmark Harness)做性能测试
文章目录使用JMH做性能测试BenchmarkModeFork和WarmupState和Scope在java中使用JMH(Java Microbenchmark Harness)做性能测试JMH的全称是Java Microbenchmark Harness,是一个open JDK中用来做性能测试的套件。该套件已经被包含在了JDK 12中。本文将会讲解如何使用JMH来在java中做性能测试。...原创 2020-03-26 09:25:48 · 10231 阅读 · 0 评论 -
java中CyclicBarrier的使用
文章目录CyclicBarrier的方法CyclicBarrier的使用java中CyclicBarrier的使用CyclicBarrier是java 5中引入的线程安全的组件。它有一个barrier的概念,主要用来等待所有的线程都执行完毕,然后再去执行特定的操作。假如我们有很多个线程,每个线程都计算出了一些数据,然后我们需要等待所有的线程都执行完毕,再把各个线程计算出来的数据加起来,的到最...原创 2020-03-25 09:26:54 · 9397 阅读 · 0 评论 -
java并发中CountDownLatch的使用
文章目录主线程等待子线程全都结束之后再开始运行等待所有线程都准备好再一起执行停止CountdownLatch的awaitjava并发中CountDownLatch的使用在java并发中,控制共享变量的访问非常重要,有时候我们也想控制并发线程的执行顺序,比如:等待所有线程都执行完毕之后再执行另外的线程,或者等所有线程都准备好了才开始所有线程的执行等。这个时候我们就可以使用到CountDownL...原创 2020-03-24 10:07:56 · 9777 阅读 · 0 评论 -
java中Locks的使用
文章目录Lock和Synchronized Block的区别Lock interfaceReentrantLockReentrantReadWriteLockStampedLockConditionsjava中Locks的使用之前文章中我们讲到,java中实现同步的方式是使用synchronized block。在java 5中,Locks被引入了,来提供更加灵活的同步控制。本文将会深入的讲...原创 2020-03-23 09:52:15 · 9373 阅读 · 0 评论 -
java 中的fork join框架
文章目录ForkJoinPoolForkJoinWorkerThreadForkJoinTask在ForkJoinPool中提交Taskjava 中的fork join框架fork join框架是java 7中引入框架,这个框架的引入主要是为了提升并行计算的能力。fork join主要有两个步骤,第一就是fork,将一个大任务分成很多个小任务,第二就是join,将第一个任务的结果join起来...原创 2020-03-20 09:56:07 · 9426 阅读 · 0 评论 -
java中ThreadPool的介绍和使用
文章目录Thread Pool简介Executors, Executor 和 ExecutorServiceThreadPoolExecutorScheduledThreadPoolExecutorForkJoinPooljava中ThreadPool的介绍和使用Thread Pool简介在Java中,threads是和系统的threads相对应的,用来处理一系列的系统资源。不管在windo...原创 2020-03-19 09:22:13 · 9750 阅读 · 0 评论 -
java中的daemon thread
java中的daemon threadjava中有两种类型的thread,user threads 和 daemon threads。User threads是高优先级的thread,JVM将会等待所有的User Threads运行完毕之后才会结束运行。daemon threads是低优先级的thread,它的作用是为User Thread提供服务。 因为daemon threads的低优先...原创 2020-03-18 09:07:39 · 9768 阅读 · 0 评论 -
java中interrupt,interrupted和isInterrupted的区别
文章目录isInterruptedinterruptedinterruptjava中interrupt,interrupted和isInterrupted的区别前面的文章我们讲到了调用interrupt()来停止一个Thread,本文将会详细讲解java中三个非常相似的方法interrupt,interrupted和isInterrupted。isInterrupted首先看下最简单的is...原创 2020-03-17 09:22:28 · 9879 阅读 · 0 评论 -
java中的Atomic类
文章目录问题背景Lock使用Atomicjava中的Atomic类问题背景在多线程环境中,我们最常遇到的问题就是变量的值进行同步。因为变量需要在多线程中进行共享,所以我们必须需要采用一定的同步机制来进行控制。通过之前的文章,我们知道可以采用Lock的机制,当然也包括今天我们讲的Atomic类。下面我们从两种方式来分别介绍。Lock在之前的文章中,我们也讲了同步的问题,我们再回顾一下。...原创 2020-03-16 09:23:42 · 9588 阅读 · 0 评论 -
怎么在java中关闭一个thread
怎么在java中关闭一个thread我们经常需要在java中用到thread,我们知道thread有一个start()方法可以开启一个线程。那么怎么关闭这个线程呢?有人会说可以用Thread.stop()方法。但是这个方法已经被废弃了。根据Oracle的官方文档,Thread.stop是不安全的。因为调用stop方法的时候,将会释放它获取的所有监视器锁(通过传递ThreadDeath异常实现...原创 2020-03-15 09:51:53 · 9939 阅读 · 0 评论 -
java中join的使用
java中join的使用join()应该是我们在java中经常会用到的一个方法,它主要是将当前线程置为WAITTING状态,然后等待调用的线程执行完毕或被interrupted。join()是Thread中定义的方法,我们看下他的定义: /** * Waits for this thread to die. * * <p> An invocati...原创 2020-03-14 08:56:29 · 9440 阅读 · 0 评论 -
java中线程的生命周期
文章目录java中Thread的状态NEWRunnableBLOCKEDWAITINGTIMED_WAITINGTERMINATEDjava中线程的生命周期线程是java中绕不过去的一个话题, 今天本文将会详细讲解java中线程的生命周期,希望可以给大家一些启发。java中Thread的状态java中Thread有6种状态,分别是:NEW - 新创建的Thread,还没有开始执行RU...原创 2020-03-13 10:07:45 · 11077 阅读 · 2 评论 -
java中ThreadLocal的使用
文章目录在Map中存储用户数据在ThreadLocal中存储用户数据java中ThreadLocal的使用ThreadLocal主要用来为当前线程存储数据,这个数据只有当前线程可以访问。在定义ThreadLocal的时候,我们可以同时定义存储在ThreadLocal中的特定类型的对象。ThreadLocal<Integer> threadLocalValue = new Thr...原创 2020-03-12 09:53:04 · 11509 阅读 · 0 评论 -
java中Runnable和Callable的区别
文章目录运行机制返回值的不同Exception处理java中Runnable和Callable的区别在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是java1.5添加进来的一个增强版本。本文我们会详细探讨Runnable和Callable的区别。运行机制首先看下Runnable和Callable的接口定义:@FunctionalInterface...原创 2020-03-11 09:18:36 · 14799 阅读 · 0 评论