
Java多线程与并发
文章平均质量分 79
惜暮
这个作者很懒,什么都没留下…
展开
-
Caffeine高性能缓存设计
Caffeine高性能缓存设计是否需要缓存选择合适的缓存Caffeine 的使用Caffeine高性能设计W-TinyLFU 淘汰算法的整体设计LRU和LRU的缺点TinyLFU统计频率Count–Min Sketch算法频率统计Count–Min Sketch的保新机制增加一个小window淘汰策略expireEntries 方法evictEntries 方法Pacer in TinyLFU异步...原创 2020-04-25 22:24:14 · 3336 阅读 · 1 评论 -
LockSupport-线程阻塞原语
基本介绍基本的线程阻塞原语,被用于创建锁和其他同步类上。长久以来对线程阻塞与唤醒经常我们会使用object的wait和notify,除了这种方式,JDK1.6之后并发包还提供了另外一种方式对线程进行挂起和恢复,它就是并发包子包locks提供的LockSupport。使用实例与简介public static void main(String[] args) throws Interr...原创 2018-08-07 16:04:37 · 1475 阅读 · 0 评论 -
J.U.C-Fork/Join框架
Fork/Join 框架本文主要介绍Fork/Join框架的基本原理、算法、设计思路与实现 1)什么是Fork/Join 框架 2)Fork/Join框架的算法 3)Fork/Join框架核心类以及它们之间的协作 4)Fork/Join使用实例 5)Fork/Join实现原理什么是Fork/Join 框架Fork/Join 框架是Java7 提供的一个用于执行并行任务的原创 2017-11-15 14:55:13 · 661 阅读 · 0 评论 -
J.U.C-DelayQueue原理与应用
DelayQueue原理与应用前面刚写了一篇关于 PriorityQueue 原理与应用 的文章,其实是为分析DelayQueue服务的。DelayQueue是一个延迟队列,用一句话来说就是:DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的Delayed 元素。 本文主要围绕以下几点分析DelayQueue: 1) Dela原创 2017-11-13 18:33:31 · 656 阅读 · 0 评论 -
如何捕获java线程中的逃逸的异常
由于Java线程的本质特征,当抛出异常的时候就终止了如果再进行catch,都不在一个线程里面,所以无法捕捉到异常。Java线程中,要在run()方法中把一切的异常都处理掉,可以使用try-catch块。不能让这个线程抛出异常,因为如果我们不使用特殊的方式的话,我们是无法捕获从这个线程中逃逸的异常的。异常一旦抛出了,那么这个线程就会停止运行,但是不会影响主线程和其它的线程。因为主线程和其它的线程都不知原创 2017-03-11 16:08:45 · 4922 阅读 · 1 评论 -
J.U.C--线程池ThreadPoolExecutor
这一篇博文主要讲解关于Java的线程池相关的内容,主要包括: (1) Executor接口以及其子接口 (2)Executor的生命周期 (3)Executors (4)任务拒绝策略 (5)线程池 ThreadPoolExecutor实现原理1. Executor接口以及其子接口首先来看一下线程池相关类与接口的体系结构图: 上面系很清晰显示了线程池中的常用类和接口之原创 2017-03-11 14:49:04 · 2380 阅读 · 0 评论 -
J.U.C--ThreadLocal的应用与使用原理
今天在电面网易游戏的时候,面试官问到了ThreadLocal的作用,感觉自己答的不好,只答除了作用,关于ThreadLocal底层的具体实现并没有说明白,于是赶忙看了下源码,从源码层次理解一下ThreadLocal的实现原理。1. 首先说说ThreadLocal有什么作用?ThreadLocal是为解决多线程环境下变量的并发访问提出的另外一种思路(相对于加锁来说)。当使用ThreadLocal维原创 2017-02-14 20:17:25 · 659 阅读 · 0 评论 -
J.U.C--locks--Condition
首先来解释一下Condition有什么作用:Condition的作用和Java原生的通过synchronized与wait()和nitofy()/notifyAll()方法相结合实现等待/通知模型的作用是一样的。Condition是一个多线程间协调通信的工具类。我们都知道synchronized与wait()和nitofy()/notifyAll()方法相结合可以实现等待/通知模型,也可以实现生产原创 2017-01-29 12:15:03 · 496 阅读 · 0 评论 -
J.U.C--locks--ReentrantLock
在JDK5之前对共享变量的访问只有synchronized和volatile。在JDK5.0之后增加了显示锁ReentrantLock(可重入锁、独占锁)。需要注意的是,ReentrantLock并不是用来替代synchronized的,而是作为一种高级主题,在内置加锁机制synchronized不适用时作为一个可选的高级主题。1. Lock接口Lock是一个显示锁的接口,ReentrantLoc原创 2017-01-28 21:05:24 · 459 阅读 · 0 评论 -
J.U.C--locks--AQS分析
看一下AbstractQueuedSynchronizer(以下简称AQS)的子类就可以知道,J.U.C中宣传的封装良好的同步工具类Semaphore、CountDownLatch、ReentrantLock、ReentrantReadWriteLock、FutureTask等虽然各自都有不同特征,但是其内部的实现都与AQS分不开。所以分析AQS的实现原理对其余显示锁或则同步工具类的理解很重要。1原创 2017-01-26 23:17:38 · 874 阅读 · 0 评论 -
J.U.C-包下的类分类
今天在网上发现了一个对J.U.C 包下的并发类进行了分类,主要分为了以下五部分:并发工具类显示锁原子变量类并发集合Executor线程执行器思维导图如下: 后面会根据这五部分对J.U.C做一个大致的原理分析。原创 2017-01-26 20:14:34 · 1517 阅读 · 0 评论 -
Java多线程问题总结
这篇博客是在看了微信公众号给我推送的一篇博客之后,然后根据自己的理解做的一个总结,也可以说是在别的blog的一个再总结: 参考博客:http://www.cnblogs.com/xrq730/p/5060921.html主要是关于Java多线程中的40个问题的总结:多线程有什么用?创建线程的方式start()方法和run()方法的区别Runnable接口和Callable接口的区别原创 2017-01-24 16:34:05 · 951 阅读 · 1 评论 -
死锁
Java程序无法从死锁中恢复过来,所以设计程序时一定要排除死锁的可能。死锁中的经典问题就是哲学家进餐问题。死锁的常见类型锁顺序死锁下图所示就是最典型的锁顺序死锁: ……不知道写啥,以后再写吧原创 2017-01-12 11:06:22 · 526 阅读 · 0 评论 -
J.U.C--扩展ThreadPoolExecutor
ThreadPoolExecutor是可以扩展的,它提供了几个在子类中改写的方法,比如:beforeExecute()、afterExecute()、和terminated()方法。这些方法可以扩展ThreadPoolExecutor的执行行为。比如剪监控线程池或则是添加日志之类的。下面是一个例子,给线程池添加统计信息:package thread;import org.apache.log4j.L原创 2017-01-12 10:35:55 · 417 阅读 · 0 评论 -
J.U.C--ThreadPoolExecutor的配置与使用
ThreadPoolExecutor为Executor提供了基本的实现,这些Executor是由Executors中的静态工厂方法返回的。ThreadPoolExecutor是一种灵活的、稳定的线程池,允许进行各种定制。1. Executors中的静态工厂方法其实不管是newCachedThreadPool()、newFixedThreadPool(int nThreads)还是newSingleT原创 2017-01-11 17:19:16 · 801 阅读 · 0 评论 -
设置线程池的大小
线程池的理想大小取决于被提交任务的类型以及所部属系统的特性。在系统中一般不固定线程池的大小,而是通过某种配置机制来提供。或则根据处理器的数量来决定:我们可以通过如下代码来获取处理器的数量://获取处理器的数量 System.out.println(Runtime.getRuntime().availableProcessors());这行代码可以直接输出当前机器处理器的数量。对于线程池的大小不能过原创 2017-01-11 16:56:51 · 3656 阅读 · 0 评论 -
J.U.C--Executor框架
在一般的web服务端,如果我们通过对每一个请求都创建一个线程来处理,这样确实可以提升性能,但是也有个非常严重的问题,当遇到请求峰值的时候,由于没有创建线程做限制,可能会导致创建非常多的线程,大大加重系统的负载,导致不可用的状态。对于这个问题我们可以通过使用有界阻塞队列来防止高负荷的应用程序耗尽内存。在J.U.C中提供了Executor框架来提供方便的实现。Executor的基本概念与使用Execu原创 2017-01-11 16:18:02 · 370 阅读 · 0 评论 -
J.U.C--同步工具类
前面已经介绍了:同步容器类、并发容器类、阻塞队列(BlockingQueue),接下来介绍同步工具类。 同步工具类可以是任何一个对象,只要根据自身的状态来协调线程的控制流。阻塞队列可以作为同步工具类,其余的还包括:信号量(Semaphore)、栅栏(Barrier)以及闭锁(Latch)。1.闭锁–CountDownLatch 闭锁(Latch)是一种同步工具类,可以延迟线程的进度,原创 2017-01-11 08:08:37 · 604 阅读 · 0 评论 -
J.U.C--分段锁
前言:在分析ConcurrentHashMap的源码的时候,了解到这个并发容器类的加锁机制是基于粒度更小的分段锁,分段锁也是提升多并发程序性能的重要手段之一。 在并发程序中,串行操作是会降低可伸缩性,并且上下文切换也会减低性能。在锁上发生竞争时将通水导致这两种问题,使用独占锁时保护受限资源的时候,基本上是采用串行方式—-每次只能有一个线程能访问它。所以对于可伸缩性来说最大的威胁就是独占锁。原创 2017-01-10 16:11:36 · 4259 阅读 · 0 评论 -
41. Java中的Unsafe类
Unsafe类简单讲一下这个类。Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作。这个类尽管里面的方法都是public的,但是并没有办法使用它们,JDK API文档也没有提供任何关于这个类的方法的解释。总而言之,对于Unsafe类的使用都是受限制的,只有授信的代码才能获得该类的实例转载 2017-01-07 12:58:49 · 1047 阅读 · 0 评论 -
J.U.C--并发容器类之ConcurrentHashMap
JDK5 提供了多种并发容器类来改进同步容器类的性能。同步容器类将所有对容器的访问操作全部串行化了来实现线程安全,这种方式的代价是严重降低的并发性。当多个线程竞争容器锁时,吞吐量严重降低。 并发容器类的设计是专门针对多线程并发访问设计的。JDK5中新增了ConcurrentHashMap来代替同步且基于散列的Map以及CopyOnWriteArrayList。ConcurrentHash原创 2017-01-07 12:53:57 · 509 阅读 · 0 评论 -
J.U.C--同步容器类Collections
在JDK1.2之前同步容器类包括Vector、HashTable,这两个容器通过内置锁synchronized保证了同步。后面的ArrayList、LinkedList、HashMap、LinkedHashMap等等都不是线程安全的,没有添加同步机制。但是JDK后面的Collections类也提供了这些常见容器类的同步容器类实现:将他们的状态封装起来,并对每个公共方法都进行同步,使得每次只有一个线程原创 2017-01-07 12:07:37 · 664 阅读 · 0 评论 -
J.U.C--原子变量类AtomicInteger的源码解析与原理分析
原子变量类比锁的粒度更加细,量级更轻,并且对于在多处理器系统上实现高性能的并发代码来说非常关键。原子标量类可以分为4组:标量类、更新器类、数组类以及复合变量类。最常用的就是原子变量累计就是标量类:AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference。其实原子变量类就是一种”更好的volatile”。下面我通过分析AtomicInteger来解原创 2016-12-29 17:21:25 · 684 阅读 · 0 评论 -
J.U.C--CAS用Java模拟实现
前面一篇blog讲了悲观锁以及乐观锁的各自优点,并详细的说了乐观锁的一种实现方式CAS原理以及Java对CAS的支持。Java模拟CAS的实现。 注意:锁是一种阻塞的实现方式,而CAS是一个非阻塞算法的常见实现。CAS全称比较并交换。在Java的底层对这个的实现是利用了底层的机器指令。CAS主要包含了3个操作数—-需要读写的内存位置(V)、进行比较的预期原值(A)和拟写入的新值(B)。当且仅原创 2016-12-29 14:35:37 · 1083 阅读 · 0 评论 -
J.U.C--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS
乐观锁与悲观锁首先介绍一些乐观锁与悲观锁: 悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。 乐观锁:顾名思义,就转载 2016-12-28 16:02:23 · 1525 阅读 · 0 评论 -
J.U.C--集合--生产者与消费者队列BlockingQueue
生产者与消费者队列通过wait()和notifyAll()可以解决人物之间互操作的问题,但是这是一种比较低级的方式,每次交互都必须握手,过程十分复杂。更好的方法是我们使用同步队列来解决任务之间相互协作的问题。同步队列在任何时刻都只允许一个任务插入或则删除元素,并且在队列为空时任务自动阻塞。java.util.concurrent.BlockingQueue接口提供了这个队列,并给出了几个标准实现。一原创 2016-12-28 00:17:42 · 872 阅读 · 0 评论 -
Java并发之线程之间协作
线程之间的协作1.wait()和notify()、notifyAll()方法(这些方法均属于基类Object)wait()函数的调用使当前线程A被阻塞以等待某个外部条件的发生(这个外部条件超出了当前方法的控制能力),通常这个条件由另外一个任务B来改变,当另外的这个任务B调用notify()或则notifyAll()时,线程A将被唤醒。所以wait()提供了一种不同人物之间活动的一种同步方式。 调原创 2016-12-28 00:16:35 · 1874 阅读 · 0 评论 -
Java并发之终结线程
终结任务(线程)1.在阻塞时终结1.1 线程状态一个线程可以处于以下5种状态之一:新建:已分配必要资源和初始化,有资格获取CPU时间了,之后调度器将把这个线程转变成可运行或则阻塞态就绪:只要调度器把时间片分给线程就可以运行。阻塞:线程可以运行,但有某个条件组织它运行(比如IO阻塞)。该状态下调度器将忽略该线程,直到重新进入就绪态(比如IO结束了就会重新进入就绪态)。运行状态: 线程正在占用C原创 2016-12-28 00:14:12 · 990 阅读 · 0 评论 -
Java并发之共享受限资源
当使用多线程时,多个线程之间彼此相互干涉的问题也就出现了。比如多线程爬虫时,多个线程同时维护一个uri队列,这样就可能会存在冲突。例如线程A准备取uri_a,但是线程B突然就抢走了uri_a,再比如线程A正在读取uri_b,此时线程B也来读取uri_b了。boolean 是原子的,线程安全的。 java中递增操作自身也需要多个步骤,所以不是原子操作,在递增过程中也可能被线程机制挂起。1. 解决共原创 2016-12-27 23:58:22 · 1403 阅读 · 0 评论 -
Java并发之线程机制
并发 使用并发需要解决的问题有多个,实现并发的方式也有多种。1. 基本的线程机制1.1 实现线程的基本方法:1.1.1 实现Runnable接口来定义任务通过实现Runnable接口并编写run()方法来是实现一个线程类。public class MyThread implements Runnable{ public void run(){ }}//使用:MyThread原创 2016-12-27 23:50:34 · 1459 阅读 · 0 评论