随笔分类 - 并发与多线程
并发与多线程文章
摘要:简介 在上一篇文章中的并发和ABA问题的介绍中,我们提到了要解决ABA中的memory reclamation问题,有一个办法就是使用RCU。 详见ABA问题的本质及其解决办法,今天本文将会深入的探讨一下RCU是什么,RCU和COW(Copy-On-Write)之间的关系。 RCU(Read-cop
阅读全文
摘要:简介 CAS的全称是compare and swap,它是java同步类的基础,java.util.concurrent中的同步类基本上都是使用CAS来实现其原子性的。 CAS的原理其实很简单,为了保证在多线程环境下我们的更新是符合预期的,或者说一个线程在更新某个对象的时候,没有其他的线程对该对象进
阅读全文
摘要:[toc] 怎么break java8 stream的foreach 简介 我们通常需要在java stream中遍历处理里面的数据,其中foreach是最最常用的方法。 但是有时候我们并不想处理完所有的数据,或者有时候Stream可能非常的长,或者根本就是无限的。 一种方法是先filter出我们需
阅读全文
摘要:[toc] java 8 stream中的Spliterator简介 简介 Spliterator是在java 8引入的一个接口,它通常和stream一起使用,用来遍历和分割序列。 只要用到stream的地方都需要Spliterator,比如List,Collection,IO channel等等。
阅读全文
摘要:java 8 lambda表达式中的异常处理 简介 java 8中引入了lambda表达式,lambda表达式可以让我们的代码更加简介,业务逻辑更加清晰,但是在lambda表达式中使用的Functional Interface并没有很好的处理异常,因为JDK提供的这些Functional Inter
阅读全文
摘要:[toc] java 8 Stream中操作类型和peek的使用 简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作。这两种有什么区别呢? 我们看一个peek的例子: ~~~java Stream stream = Stream.of("one", "two", "thr
阅读全文
摘要:Lambda表达式java 8引入的函数式编程框架。之前的文章中我们也讲过Lambda表达式的基本用法。
本文将会在之前的文章基础上更加详细的讲解Lambda表达式在实际应用中的最佳实践经验。
优先使用标准Functional接口
之前的文章我们讲到了,java在java.util.function包中定义了很多Function接口。基本上涵盖了我们能够想到的各种类型。
假如我们自定义了下面的Functional interface
阅读全文
摘要:Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的。这里主要是两个线程之间交换持有的对象。当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法。
两个线程都调用exchange方法之后,传入的参数就会交换
阅读全文
摘要: java 8引入了lambda表达式,lambda表达式实际上表示的就是一个匿名的function。 在java 8之前,如果需要使用到匿名function需要new一个类的实现,但是有了lam
阅读全文
摘要:java内存模型(JMM)和happens-before
我们知道java程序是运行在JVM中的,而JVM就是构建在内存上的虚拟机,那么内存模型JMM是做什么用的呢?
阅读全文
摘要:上篇文章我们讲到了使用锁会带来的各种缺点,本文将会讲解如何使用非阻塞算法。非阻塞算法一般会使用CAS来协调线程的操作。
虽然非阻塞算法有诸多优点,但是在实现上要比基于锁的算法更加繁琐和负责。
本文将会介绍两个是用非阻塞算法实现的数据结构
阅读全文
摘要:我们知道在java 5之前同步是通过Synchronized关键字来实现的,在java 5之后,java.util.concurrent包里面添加了很多性能更加强大的同步类。这些强大的类中很多都实现了非阻塞的同步机制从而帮助其提升性能
阅读全文
摘要:
我们之前介绍了很多同步类,比如ReentrantLock,Semaphore, CountDownLatch, ReentrantReadWriteLock,FutureTask等。
AQS封装了实现同步器时设计的大量细节问题。他提供了FIFO的wait queues并且提供了一个int型的state表示当前的状态。
根据JDK的说明,并不推荐我们直接使用AQS,我们通常需要构建一个内部类来继承AQS并按照需要重写下面几个方法
阅读全文
摘要:为了保证线程的安全,我们引入了加锁机制,但是如果不加限制的使用加锁,就有可能会导致顺序死锁(Lock-Ordering Deadlock)。上篇文章我们也提到了在线程词中因为资源的不足而导致的资源死锁(Resource Deadlock)。 本文将会讨论一下顺序死锁的问题。 我们来讨论一个经常存在的
阅读全文
摘要:文章目录AbortPolicyDiscardPolicyDiscardOldestPolicyCallerRunsPolicy使用Semaphore java中有界队列的饱和策略(reject policy) 我们在使用ExecutorService的时候知道,在ExecutorService中有个
阅读全文
摘要:我们在构建线程池的时候可以构建单个线程的线程池和多个线程的线程池。 那么线程池使用不当可不可能产生死锁呢?我们知道死锁是循环争夺资源而产生的。线程池中的线程也是资源的一种,那么如果对线程池中的线程进行争夺的话也是可能产生死锁的。 在单个线程的线程池中,如果一个正在执行的线程中,使用该线程池再去提交第
阅读全文
摘要:文章目录使用shutdown使用shutdownNow 使用ExecutorService来停止线程服务 之前的文章中我们提到了ExecutorService可以使用shutdown和shutdownNow来关闭。 这两种关闭的区别在于各自的安全性和响应性。shutdownNow强行关闭速度更快,但
阅读全文
摘要:java中CompletionService的使用 之前的文章中我们讲到了ExecutorService,通过ExecutorService我们可以提交一个个的task,并且返回Future,然后通过调用Future.get方法来返回任务的执行结果。 这种方式虽然有效,但是需要保存每个返回的Futu
阅读全文
摘要:文章目录使用HashMap使用ConcurrentHashMapFutureTask 在java中构建高效的结果缓存 缓存是现代应用服务器中非常常用的组件。除了第三方缓存以外,我们通常也需要在java中构建内部使用的缓存。那么怎么才能构建一个高效的缓存呢? 本文将会一步步的进行揭秘。 使用HashM
阅读全文
摘要:java中使用Semaphore构建阻塞对象池 Semaphore是java 5中引入的概念,叫做计数信号量。主要用来控制同时访问某个特定资源的访问数量或者执行某个操作的数量。 Semaphore中定义了一组虚拟的permits,通过获取和释放这些permits,Semaphore可以控制资源的个数
阅读全文