concurrent包
来源:互联网 发布:怎样退货给淘宝卖家 编辑:程序博客网 时间:2024/05/18 07:15
参考博文:http://www.cnblogs.com/sarafill/archive/2011/05/18/2049461.html
http://blog.csdn.net/wulei_longhe/article/details/30032031
• JVM 级别更改。大多数现代处理器对并发提供某一硬件级别的支持,通常以 compare-and-swap (CAS)指令形式。CAS 是一种低级别的、细粒度的技术,它允许多个线程更新一个内存位置,同时能够检测其他线程的冲突并进行恢复。它是许多高性能并发算法的基础。在 JDK 5.0 之前,Java 语言中用于协调线程之间的访问的惟一原语是同步,同步是更重量级和粗粒度的。 CAS 可以开发高度可伸缩的并发 Java 类。这些更改主要由 JDK 库类使用,而不是由开发人员使用。
• 低级实用程序类 -- 锁定和原子类。使用 CAS 作为并发原语,ReentrantLock 类提供与 synchronized 原语相同的锁定和内存语义,然而这样可以更好地控制锁定(如计时的锁定等待、锁定轮询和可中断的锁定等待)和提供更好的可伸缩性(竞争时的高性能)。大多数开发人员将不再直接使用 ReentrantLock 类,而是使用在 ReentrantLock 类上构建的高级类。
• 高级实用程序类。这些类实现并发构建块,每个计算机科学文本中都会讲述这些类 -- 信号、互斥、闩锁、屏障、交换程序、线程池和线程安全集合类等。大部分开发人员都可以在应用程序中用这些类,来替换许多(如果不是全部)同步、wait() 和 notify() 的使用,从而提高性能、可读性和正确性。
一、Semaphore-计数信号量
从概念上讲,信号量维护了一个许可集。通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。acquire()表示可以从信号量获取一个许可,提供之前线程将会阻塞。release()表示释放许可,并返回给信号量。用法如下:
01
import
java.util.concurrent.ExecutorService;
02
import
java.util.concurrent.Executors;
03
import
java.util.concurrent.Semaphore;
04
public
class
MySemaphore
extends
Thread {
05
Semaphore position;
06
private
int
id;
07
public
MySemaphore(
int
i,Semaphore s){
08
this
.id=i;
09
this
.position=s;
10
}
11
public
void
run(){
12
try
{
13
if
(position.availablePermits()>
0
){
14
System.out.println(
"顾客["
+
this
.id+
"]进入厕所,有空位"
);
15
}
16
else
{
17
System.out.println(
"顾客["
+
this
.id+
"]进入厕所,没空位,排队"
);
18
}
19
position.acquire();
20
System.out.println(
"顾客["
+
this
.id+
"]获得坑位"
);
21
Thread.sleep((
int
)(Math.random()*
1000
));
22
System.out.println(
"顾客["
+
this
.id+
"]使用完毕"
);
23
position.release();
24
}
25
catch
(Exception e){
26
e.printStackTrace();
27
}
28
}
29
public
static
void
main(String args[]){
30
ExecutorService list=Executors.newCachedThreadPool();
31
Semaphore position=
new
Semaphore(
2
);
32
for
(
int
i=
0
;i<
10
;i++){
33
list.submit(
new
MySemaphore(i+
1
,position));
34
}
35
list.shutdown();
36
position.acquireUninterruptibly(
2
);
37
System.out.println(
"使用完毕,需要清扫了"
);
38
position.release(
2
);
39
}
40
}
二、CompletionService
将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者 submit 执行的任务。使用者take 已完成的任务,并按照完成这些任务的顺序处理它们的结果,即使用 Producer/Consumer 模式,其中生产者创建任务并提交,消费者请求完成任务的结果并处理这些结果。CompletionService 依赖于一个单独的Executor
来实际执行任务,在这种情况下,CompletionService 只管理一个内部完成队列。ExecutorCompletionService
类提供了此方法的一个实现。用法如下:
01
import
java.util.concurrent.Callable;
02
import
java.util.concurrent.CompletionService;
03
import
java.util.concurrent.ExecutorCompletionService;
04
import
java.util.concurrent.ExecutorService;
05
import
java.util.concurrent.Executors;
06
public
class
MyCompletionService
implements
Callable<String> {
07
private
int
id;
08
09
public
MyCompletionService(
int
i){
10
this
.id=i;
11
}
12
public
static
void
main(String[] args)
throws
Exception{
13
ExecutorService service=Executors.newCachedThreadPool();
14
CompletionService<String> completion=
new
ExecutorCompletionService<String>(service);
15
for
(
int
i=
0
;i<
10
;i++){
16
completion.submit(
new
MyCompletionService(i));
17
}
18
for
(
int
i=
0
;i<
10
;i++){
19
System.out.println(completion.take().get());
20
}
21
service.shutdown();
22
}
23
public
String call()
throws
Exception {
24
Integer time=(
int
)(Math.random()*
1000
);
25
try
{
26
System.out.println(
this
.id+
" start"
);
27
Thread.sleep(time);
28
System.out.println(
this
.id+
" end"
);
29
}
30
catch
(Exception e){
31
e.printStackTrace();
32
}
33
return
this
.id+
":"
+time;
34
}
35
}
三、CountdownLatch
有两个重要的方法:
await():使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断
countDown():递减锁存器的计数,如果计数到达零,则释放所有等待的线程
下面以模拟运动员比赛说明用法:
import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownLatchDemo { private static final int PLAYER_AMOUNT = 5; public CountDownLatchDemo() { // TODO Auto-generated constructor stub } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub //对于每位运动员,CountDownLatch减1后即结束比赛 CountDownLatch begin = new CountDownLatch(1); //对于整个比赛,所有运动员结束后才算结束 CountDownLatch end = new CountDownLatch(PLAYER_AMOUNT); Player[] plays = new Player[PLAYER_AMOUNT]; for(int i=0;i<PLAYER_AMOUNT;i++) plays[i] = new Player(i+1,begin,end);//设置特定的线程池,大小为5
ExecutorService exe = Executors.newFixedThreadPool(PLAYER_AMOUNT); for(Player p:plays) exe.execute(p); //分配线程 System.out.println("Race begins!"); begin.countDown(); try{ end.await(); //等待end状态变为0,即为比赛结束 }catch (InterruptedException e) { // TODO: handle exception e.printStackTrace(); }finally{ System.out.println("Race ends!"); } exe.shutdown(); } }
public class Player implements Runnable { private int id; private CountDownLatch begin; private CountDownLatch end; public Player(int i, CountDownLatch begin, CountDownLatch end) { // TODO Auto-generated constructor stub super(); this.id = i; this.begin = begin; this.end = end; } @Override public void run() { // TODO Auto-generated method stub try{ begin.await(); //等待begin的状态为0 Thread.sleep((long)(Math.random()*100)); //随机分配时间,即运动员完成时间 System.out.println("Play"+id+" arrived."); }catch (InterruptedException e) { // TODO: handle exception e.printStackTrace(); }finally{ end.countDown(); //使end状态减1,最终减至0 } } }
四、CyclicBarrier
允许一组线程互相等待,直到所有子线程都到达了这个屏障时,再一起继续执行后面的动作。
两个重要方法:
await():在所有参与者都已经在此 barrier 上调用await 方法之前,将一直等待
getParties():返回要求启动此 barrier 的参与者数目
下面举例来说明用法:
年末公司组织团建,要求每一位员工周六上午8点【自驾车】到公司门口集合,然后【自驾车】前往目的地。 在这个案例中,公司作为主线程,员工作为子线程。
package com.test.spring.support;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CountDownLatch;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;/** * @author javaloveiphone * @date 创建时间:2017年1月25日 上午10:59:11 * @Description: */public class Company { public static void main(String[] args) throws InterruptedException { //员工数量 int count = 5; //创建计数器 CyclicBarrier barrier = new CyclicBarrier(count+1); //创建线程池,可以通过以下方式创建 //ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1,1,60,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(count)); ExecutorService threadPool = Executors.newFixedThreadPool(count); System.out.println("公司发送通知,每一位员工在周六早上8点【自驾车】到公司大门口集合"); for(int i =0;i<count ;i++){ //将子线程添加进线程池执行 threadPool.execute(new Employee(barrier,i+1)); Thread.sleep(10); } try { //阻塞当前线程,直到所有员工到达公司大门口之后才执行 barrier.await(); Thread.sleep(10); // 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。 //latch.await(long timeout, TimeUnit unit) System.out.println("所有员工已经到达公司大门口,公司领导一并【自驾车】同员工前往活动目的地。"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); }finally{ //最后关闭线程池,但执行以前提交的任务,不接受新任务 threadPool.shutdown(); //关闭线程池,停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。 //threadPool.shutdownNow(); } }}//分布式工作线程class Employee implements Runnable{ private CyclicBarrier barrier; private int employeeIndex; public Employee(CyclicBarrier barrier,int employeeIndex){ this.barrier = barrier; this.employeeIndex = employeeIndex; } @Override public void run() { try { System.out.println("员工:"+employeeIndex+",正在前往公司大门口集合..."); Thread.sleep(10*employeeIndex); System.out.println("员工:"+employeeIndex+",已到达。"); barrier.await(); Thread.sleep(10); System.out.println("员工:"+employeeIndex+",【自驾车】前往目的地"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } }}
公司发送通知,每一位员工在周六早上8点【自驾车】到公司大门口集合员工:1,正在前往公司大门口集合...员工:1,已到达。员工:2,正在前往公司大门口集合...员工:3,正在前往公司大门口集合...员工:2,已到达。员工:4,正在前往公司大门口集合...员工:5,正在前往公司大门口集合...员工:3,已到达。员工:4,已到达。员工:5,已到达。员工:3,【自驾车】前往目的地员工:5,【自驾车】前往目的地所有员工已经到达公司大门口,公司领导一并【自驾车】同员工前往活动目的地。员工:4,【自驾车】前往目的地员工:1,【自驾车】前往目的地员工:2,【自驾车】前往目的地
- concurrent包
- concurrent包
- Concurrent包
- concurrent包
- concurrent 包
- concurrent包
- concurrent包
- Concurrent包
- java.util.concurrent包
- java.util.concurrent包
- concurrent包小结(转)
- java concurrent包浅析
- concurrent包Callable接口
- concurrent并发包结构
- java.util.concurrent包
- Concurrent包中ConcurrentHashMap
- Java concurrent包
- Concurrent包详解
- Android Issue Sharing
- 第十六天,jsp,el表达式
- Android BroadcastReceiver
- 4-20mA 0-5V工业标准信号回望笔录
- COGS1442 [NOIP2013] 华容道
- concurrent包
- android中解析xml
- 《数字图像处理》第三版笔记(六)频率域滤波
- java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector
- GSON
- MobX 入门教程
- 指针实现 strcpy()字符串拷贝
- Batch Normalization导读
- android 通过代理activity的方式实现插件化