Java并发编程小记
1. Semaphore
信号量是一种计数器,用来保护一个或者多个共享资源的访问。如果线程要访问一个共享资源,必须先获得信号量。若内部计数器大于0,则减1,若等于0,则线程进入休眠直至计数器大于等于0。
Semaphore semaphore1 = new Semaphore(); // 值为1的信号量
Semaphore semaphore2 = new Semaphore(, true); // 公平模式,FIFO
semaphore1.acquire(); // 获取资源,否则阻塞,且在阻塞过程中可以被中断
semaphore1.acquireUninterruptibly(); // 获取资源,否则阻塞,且在阻塞过程中不可被中断
semaphore1.tryAcquire(); // 尝试获取
semaphore1.release(); // 释放
2. CountDownLatch
CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。若一个线程需要等待某些操作先执行完,需调用await()方法进入休眠,当一个操作完成,则调用countDown()将内部计数器减1,若变为0时,则唤醒所有因调用await()而进入休眠的线程。
CountDownLatch机制不是用来保护共享资源或者临界区的,它是用来同步执行多个任务的一个或者多个线程。
CountDownLatch不能被重置。
CountDownLatch controller = new CountDownLatch(number); // 计数器为number
controller.countDown(); // 计数器减1
controller.getCount(); // 获取计数器的值
controller.await(); // 等待计数器变0
3. CyclicBarrier
CyclicBarrier是一个同步辅助类,它允许两个或者多个线程在某个点上进行同步。当一个线程到达指定的点后,调用await()方法休眠并等待其他的线程,当最后一个的await()方法被调用时,CyclicBarrier将唤醒所有在等待的线程然后这些线程将继续执行。
CyclicBarrier还可以传入另一个Runnable对象作为之后运行的线程。
CyclicBarrier可以被重置。
CyclicBarrier barrier = new CyclicBarrier(, task); // 需要集合5个线程,并且之后运行task
barrier.await(); // 休眠等待
barrier.await(long, TimeUnit); // 保持休眠直到被中断。或者内部计数器变为0,或者时间过期
barrier.getNumberWaiting(); // 返回阻塞线程数目
barrier.getParties(); // 返回对象同步的任务数
barrier.reset(); // 重置对象,await()的线程抛出一个BrokenBarrierException
barrier.isBroken(); // 判断对象是否损坏,这种状态在其中一个线程被中断抛出InterruptedException时出现
4. Phaser
一个辅助类,允许执行并发多阶段任务,在每一步结束时对线程进行同步。
需要对同步操作的任务数进行初始化,但是可以动态地增加或者减少任务数。
Phaser不会被中断响应。
Phaser phaser = new Phaser(); // 需要3个线程同步
phaser.arriveAndAwaitActive(); // 等待3个线程到达此执行点
phaser.arriveAndDeregister(); // 减少一个需要同步的线程
phaser.onAdvance(); // 返回true则说明处于终止态
phaser.isFinalized();
Phaser还提供其他改变对象的方法。
Phaser phaser = new Phaser(); // 需要3个线程同步
phaser.arrive(); // 通知一个参与者已经完成了当前阶段,不应该等待其他参与者,故不会同步
phaser.awaitAdvance(int); // 若传入参数与当前阶段一致,则当前线程休眠直到这个阶段参与者都完成;否则立即返回
phaser.awaitAdvanceInterruptibly(int); // 若被中断抛出异常
phaser.register(); // 注册一个新的参与者
phaser.register(int); // 批量注册
phaser.forceTermination(); // 强制终止
5. Exchanger
一个辅助类,允许在两个线程之间定义同步点,当两个线程都到达同步点时,交换他们的数据结构。
Exchanger<List<String>> exchanger = new Exchanger<List<String>>();
List<String> buffer = new List<String>();
buffer = exchanger.exchange(buffer);
6. Executor
分离了任务的创建和执行,只需要传递实现了Runnable接口的对象,通过执行器创建所需的线程,来负责Runnable对象的创建、实例化以及运行。其使用了线程池来提高程序的性能。
执行期框架另外的优势是Callable接口,将获得一个实现了Future接口的对象,用其控制Callable对象的状态和结果。
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newCachedThreadPool(); // 创建一个缓存线程池
executor.execute(task); // 传递实现Runnable或Callable接口的对象
executor.getPoolSize(); // 返回执行器线程池中的实际线程数
executor.getActiveCount(); // 返回正在执行任务的线程数
executor.getCompletedTaskCount(); // 返回执行器已经完成的任务数
executor.getLargestPoolSize(); // 获取曾经同时位于线程池中的最大线程数
executor.shutdown(); // 结束
executor.shutdownNow(); // 立即关闭执行器,返回等待执行的任务列表
executor.isTerminated(); // 若已调研shutdown()或shutdownNow()返回true
executor.isShutdown(); // 若已调用shutdown()返回true
executor.awaitTermination(long, TimeUnit); // 阻塞所调用的线程,直到完成任务或者达到所指定的timeout值
创建固定大小的Executor:
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(int); // 创建一个固定大小的线程池
Future相关:
public class FactorialCal implements Callable<Integer> {
@Override
public Integer call() throws Exception { }
} // 创建实现Callable接口的实例
Future<Integer> result = executor.submit(new FactorialCal()); // 获取结果
Integer number = result.get(); // 获取Integer,若未完成则一直阻塞
Integer number = result.get(long, TimeUnit); // 等待指定的时间,若未完成则返回null
result.isDone(); // 检查任务是否完成
其他方法:
executor.invokdeAny(Collection<? extends Callable<T>>); // 实现任一后返回结果
executor.invokdeAny(Collection<? extends Callable<T>>); // 实现全部后返回结果
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executor.newScheduledThreadPool();
executor.schedule(new Task(), int, TimeUnit);
ScheduledFuture<?> result = executor.scheduleAtFixedRate(new Task(), int, int, TimeUnit); // 循环任务
Java并发编程小记的更多相关文章
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- JAVA并发编程J.U.C学习总结
前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...
随机推荐
- ios禁用多按钮同时点下的效果
只需要把那些不能同时点下的按钮或者视图设置一下即可. [view setExclusiveTouch:YES]; 避免view上多个button同时按下,则可设置每个button的setExclusi ...
- Reward HDU
Reward Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32 ...
- C#读写word
操作word之前需要在COM引入Microsoft Office 12.0 Object Library(文件库可能不一样) 然后添加using Microsoft.Office.Interop.Wo ...
- Unity3d Web Player 的server端联网配置
新游戏出了第一个能跑完流程的版本,不得不佩服Unity3D强大的功力,PC.MAC OS.Linux.IOS.Android.web player,前天刚发布的unity3d 4.2版本还支持WIND ...
- 几项有用的JQUERY代码
检测IE浏览器 在进行CSS设计时,IE浏览器对开发者及设计师而言无疑是个麻烦.尽管IE6的黑暗时代已经过去,IE浏览器家族的人气亦在不断下滑,但我们仍然有必要对其进行检测.当然,以下片段亦可用于检测 ...
- WordPress插件制作教程(一): 如何创建一个插件
上一篇还是按照之前的教程流程,写了一篇WordPress插件制作教程概述,从这一篇开始就为大家具体讲解WordPress插件制作的内容.这一篇主要说一下插件的创建方法. 相信大家都知道插件的安装文件在 ...
- nginx+keepalived+tomcat之具体配置档
前沿知识点: nginx负责负载均衡(反向代理) msm(memcached session manager)负责缓存会话信息,从而实现会话保持 所需包: nginx和memcached采用最新稳定版 ...
- information_schema.events 学习
information_schema.events 表保存了整个mysql实例中的event 信息 1.常用列: 1.event_catalog :永远是def 2.event_schema :eve ...
- 线程初步了解 - <第一篇>
操作系统通过线程对程序的执行进行管理,当操作系统运行一个程序的时候,首先,操作系统将为这个准备运行的程序分配一个进程,以管理这个程序所需要的各种资源.在这些资源之中,会包含一个称为主线程的线程数据结构 ...
- SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案
原文:SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Serv ...