并发编程
冻冰粉星
梧高凤至,花香蝶来。
展开
-
CopyOnWrite学习及分析
CopyOnWrite有两个相关的类,CopyOnWriteArrayList及CopyOnWriteArraySet,所以支持去重操作,它是基于读写分离的,也就是在读的时候是在原集合上读取数据,在写的时候它是先把原集合复制一份,然后在对元素进行写操作。 CopyOnWriteArrayList<String> cowa = new CopyOnWriteArrayList...原创 2018-11-23 18:32:12 · 193 阅读 · 0 评论 -
Exchanger的用法
Exchanger一般用的比较少,它的作用是在两个线程中进行数据交换。下面做一个例子进行说明。例子:起两个线程,线程A 线程B ,它们分别各自处理自己的数据,然后进行数据交换。import java.util.concurrent.Exchanger;import java.util.concurrent.ExecutorService;import java.util.concur...原创 2018-12-02 21:29:54 · 516 阅读 · 0 评论 -
Unsafe类
Unsafe类是sun.misc包下的类,是单例的。java本身不能对操作系统底层进行操作,但是Unsafe类提供了一些方法可以实现硬件级别的原子操作。Unsafe类提供一下一些功能:内存操作:对内存分配、内存装载等对象字段的定位及修改线程的挂起与恢复CAS操作下面是一个小例子来说明Unsafe类对内存的修改import java.lang.reflect.Field...原创 2018-11-28 13:17:45 · 199 阅读 · 0 评论 -
CountDownLatch的使用
CountDownLatch是java.util.concurrent包中的类,它的作用是1个线程等待,多个线程唤醒此等待。CountDownLatch cdl = new CountDownLatch(2);通过构造方法声明CountDownLatch对象,2这个参数说明一共3个线程。1个线程执行时需要等待,其它的2个线程都进行唤醒操作之后前面的等待线程才能继续执行。//在此等待...原创 2018-11-28 14:10:36 · 198 阅读 · 0 评论 -
CyclicBarrier的使用
CyclicBarrier是java.util.Concurrent包中的类,它的作用是多个线程并行只执行时,在一个临界条件下同时执行,未达到此临界条件则进行阻塞等待,达到临界条件后不需要唤醒立即执行。//需4个线程并行执行CyclicBarrier cb = new CyclicBarrier(4);//阻塞等待cb.await();完整模拟事例:import java...原创 2018-11-28 14:55:41 · 165 阅读 · 0 评论 -
Semaphore信号量相关
系统上线之前需要做一系列的评估来确保系统稳定,Semphore非常适合高并发访问限制。相关概念PV(Page View):网站的总访问量,页面浏览量货点击量,用户每刷新一次就会被记录一次。UV(Unique Visitor):访问网站的一台电脑客户端为一个访客。QPS(Query Per Second):每秒查询数。RT(Response Time):请求的响应时间。容量评...原创 2018-12-05 17:40:41 · 133 阅读 · 0 评论 -
线程池
线程池的作用:管理控制:线程池可以更好的控制线程,使我们可以对线程的生命周期、初始化、运行状态、销毁等各个环节有一个把控。系统资源:线程池可以控制线程的数量,根据任务的多少去对线程池中的线程个数进行添加或减少,可以回收空闲状态的线程,减少线程的频繁初始化和销毁,避免不必要的系统开销,节省系统资源。保障稳定性。应用性能:线程池可以配合高并发容器的设置,异步多线程的去处理任务,提高应用服务...原创 2018-12-14 14:53:15 · 118 阅读 · 0 评论 -
AQS-ReentrantLock
AQS是jdk中的一个类:AbstractQueuedSynchronizer,很多并发容器底层是由这个类来实现的。它定义了多个线程访问资源的一个同步类容器。比如:ReentrantLock/Semaphore/CountDownLatch。AQS里面维护了一个共享的参数private volatile int state,以及一个先进先出的线程等待队列,访问state有3种方式:getS...原创 2018-12-18 11:31:07 · 121 阅读 · 0 评论 -
Condition的使用
ReentrantLock与Condition一起使用可以更灵活、更方便的控制线程之间的等待唤醒操作。import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public cla...原创 2018-12-18 15:23:37 · 404 阅读 · 0 评论 -
ReentrantReadWriteLock的使用
ReentrantReadWriteLock的使用很简单,它其实是ReentrantLock的升级版,在并发读写的时候应用广泛。它提供了获取读锁和写锁的方法,在调用读写锁的时候,读锁可以并发同时调用,但是写锁只能一个线程调用其他线程等待。import java.util.concurrent.locks.ReentrantReadWriteLock;import java.util.c...原创 2018-12-18 15:56:39 · 1989 阅读 · 2 评论 -
volatile的使用及分析
vlolatile修饰的变量可以做为共享变量,在多线程中可见。意思是,在一个线程中volatile修饰的变量修改了,其他调用此变量的线程中同样可以看到修改。场景两个线程A、B,B在A中,A修改了B中的变量值,B中可以看到修改。代码public class UseVolatile extends Thread{ private int count = 0; private v...原创 2018-11-27 18:28:22 · 242 阅读 · 0 评论 -
一个经典面试题
如题,有两个线程A、B,A线程向一个集合(List<String>)中依次添加元素“abc”字符串,一共添加10次,当添加到第五次后,希望B线程能接收到A线程的通知,然后B线程执行相关的业务操作,我们应该如何进行设计?解析:这道题很简单,设计两个线程,A线程for循环添加10次“abc”,B线程获取list的size,当长度为5时,执行业务逻辑,而不对A线程产生影响。解题方式(...原创 2018-11-26 22:02:20 · 132 阅读 · 0 评论 -
java.util.ConcurrentModificationException异常
事例通常在操作集合的时候,如ArrayList,遍历删除元素的时候,有可能导致java.util.ConcurrentModificationException异常,如下:1.for循环 public static void methodRemove(List<String> list) { for(String s:list) { if("3".equals(s))...原创 2018-11-22 18:11:11 · 193 阅读 · 0 评论 -
将普通的集合转成线程安全的集合
我们都知道ArrayList并不是现成安全地集合,那怎么操作将之变成线程安全的集合呢?jdk的Collections类提供了一些Collection.synchronized*的方法。如: public static <T> Collection<T> synchronizedCollection(Collection<T> c) { ...原创 2018-11-23 12:09:27 · 1061 阅读 · 0 评论 -
模拟阻塞队列-MyBlockingQueue
什么是阻塞队列?阻塞队列也就是支持阻塞的队列。包括阻塞添加和阻塞移除,也就是锁的wait 和 notify 操作。当队列满时,再添加元素就会阻塞插入队列的线程,直到队列不满;当队列为空时,就会阻塞获取元素的线程,直到队列不为空;注意点队列,也就是存放数据的容器或集合,是有固定最大长度的;需要有一个计数器,记录队列长度;队列没有元素时,执行的线程要等待;队列元素已满时...原创 2018-11-24 19:57:56 · 868 阅读 · 0 评论 -
SynchronousQueue
SynchronousQueue是一个即时的没有缓冲的队列,首先需要一个线程获取元素,队列中没有元素,线程就会等待,当另外一个线程往队列中添加元素后,前一个线程会获取到元素。 SynchronousQueue<String> sq = new SynchronousQueue<>(); sq.add("张三");上面代码main中执行,直接报异常,因为没有线...原创 2018-11-26 08:56:15 · 139 阅读 · 0 评论 -
PriorityBlockingQueue使用
priorityBlockingQueue是一个无界队列,它没有限制,在内存允许的情况下可以无限添加元素;它又是具有优先级的队列,是通过构造函数传入的对象来判断,传入的对象必须实现comparable接口。首先创建一个person对象,里面有id name 两个属性,person实现了comparable接口,并重写compareTo方法public class Person imple...原创 2018-11-26 09:55:15 · 17387 阅读 · 0 评论 -
DelayQueue的使用
DelayQueue是一个元素具有延迟属性的无界队列。它的元素必须实现Delayed接口,当过期时间到了的时候,才能获取到这个元素,进行操作。它的使用场景很多,都是涉及到延迟过期相关业务的,比如redis缓存、系统内存数据过期等等。下面模拟网吧上网的场景。网民去网吧上网,交钱获取上网时间就能上机,时间到下机,就是这个场景。首先,定义网民对象,实现Delayed接口,重写里面的方法。i...原创 2018-11-26 15:10:01 · 597 阅读 · 0 评论 -
模拟Future模式
多线程里的Future模式的主要特点是,一个大的业务中,有好多耗时比较多的任务,如果按照顺序一个一个的完成,所用的时间就是所有的任务耗时累和,但是其实有一些任务是可以并行执行的,所以不必一个任务一个任务逐一完成,只需要另外开线程做任务,当需要任务结果时获取结果数据就ok了。简单说就是主任务向下执行,具体到某个小任务的时候,开一个线程不阻塞异步执行。 如图,需要有一个客户端来发送请求,需要有...原创 2018-12-02 14:38:29 · 475 阅读 · 0 评论 -
ForkJoin框架
ForkJoin是jdk7以后加入的,它的作用是对一个大任务进行拆分,可以无限拆分,若需要返回结果,则进行合并。需要继承ForkJoinTask的子类:RecursiveTask:需要返回结果的RecursiveAction:不需要返回结果的需要定义域值,也就是判断什么时候开始拆分,定义拆分的规则,比如二分法等等下面是一个例子:等差数列求和:1+3+5+9+……+199=?...原创 2018-12-04 10:22:42 · 126 阅读 · 0 评论 -
LockSupport的使用
LockSupport可以唤醒1个线程的等待,不需要使用Synchronized wait notify 等操作,所以,在对一个线程进行等待唤醒才做时非常方便。但是如果是多线程之间的阻塞唤醒,做好还是用ReentrantLock等方式。import java.util.concurrent.locks.LockSupport;public class UseLockSupport { ...原创 2018-12-18 16:30:14 · 234 阅读 · 0 评论