同步工具类(闭锁,信号量,栅栏,FutureTask)
来源:互联网 发布:淘宝退货用空包判刑吗 编辑:程序博客网 时间:2024/05/19 03:42
闭锁:可以延迟线程的进度直到其到达终止状态。
public class LatchDemo {
public static long timeTasks(int nThreads, final Runnable task)
throws InterruptedException {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {
Thread t = new Thread() {
public void run() {
try {
startGate.await();//等待所有线程到来
try {
task.run();
} finally {
endGate.countDown();//确定所有线程完成
}
} catch (InterruptedException ignored) {
}
}
};
t.start();
}
long start = System.nanoTime();
startGate.countDown();//表示有一个事件发生
endGate.await();//等待计数器清零,表示所有需要等待的事件都已经发生
long end = System.nanoTime();
return end - start;
}
public static void main(String[] args) throws InterruptedException{
System.out.println(timeTasks(5, new Demo()));
}
}
class Demo implements Runnable{
public void run() {
System.out.println("hello");
}
}
结果:
hello
hello
hello
hello
1027743
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
信号量:用来控制同时访问某个特定的操作数量,或者同时执行某个指定操作的数量。另外,信号量还可以用来实现某种资源池,或者对容器加边界。
public class SemaphoreTest<T> {
private final Set<T> set;
private final Semaphore sema;
public SemaphoreTest(int bound){
this.set = Collections.synchronizedSet(new HashSet<T>());
this.sema = new Semaphore(bound);
}
public boolean add(T o) throws InterruptedException{
sema.acquire();
boolean wasAdded = false;
try{
wasAdded = set.add(o);
System.out.println(wasAdded);
return wasAdded;
}finally{
if(!wasAdded){
sema.release();
}
}
}
public boolean remove(T o){
boolean wasRemoved = set.remove(o);
if(wasRemoved){
sema.release();
}
return wasRemoved;
}
public static void main(String[] args) throws InterruptedException{
int permits = 3;//允许多少个,true有多少个
int elements = permits + 1;
SemaphoreTest<Integer> test = new SemaphoreTest<Integer>(permits);
for(int i = 0;i < elements; i++){
test.add(i);
}
}
}
结果:输出三个true(true的个数和permits参数一致)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
栅栏:类似于闭锁,它能阻塞一组线程知道某个事件发生。并能重复进行计算多次,而闭锁不能实现重复计算。
public class CyclicBarrierTest {
private final CyclicBarrier barrier;
private final Worker[] workers;
public CyclicBarrierTest(){
int count = Runtime.getRuntime().availableProcessors();
this.barrier = new CyclicBarrier(count,
new Runnable(){
@Override
public void run() {
System.out.println("所有线程均到达栅栏位置,开始下一轮计算");
}
});
this.workers = new Worker[count];
for(int i = 0; i< count;i++){
workers[i] = new Worker(i);
}
}
private class Worker implements Runnable{
int i;
public Worker(int i){
this.i = i;
}
@Override
public void run() {
for(int index = 1; index < 3;index++){
System.out.println("线程" + i + "第" + index + "次到达栅栏位置,等待其他线程到达");
try {
//注意是await,而不是wait
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
return;
} catch (BrokenBarrierException e) {
e.printStackTrace();
return;
}
}
}
}
public void start(){
for(int i=0;i<workers.length;i++){
new Thread(workers[i]).start();
}
}
public static void main(String[] args){
new CyclicBarrierTest().start();
}
}
结果:
线程1第1次到达栅栏位置,等待其他线程到达
线程3第1次到达栅栏位置,等待其他线程到达
线程2第1次到达栅栏位置,等待其他线程到达
线程0第1次到达栅栏位置,等待其他线程到达
所有线程均到达栅栏位置,开始下一轮计算
线程3第2次到达栅栏位置,等待其他线程到达
线程2第2次到达栅栏位置,等待其他线程到达
线程1第2次到达栅栏位置,等待其他线程到达
线程0第2次到达栅栏位置,等待其他线程到达
所有线程均到达栅栏位置,开始下一轮计算
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
FutureTask:通过将FutureTask封装进线程,通过启动线程提前启动计算,若数据已经加载,那么将返回这些数据,否则将等待加载完成后再返回。
public class Preloader {
ProductInfo loadProductInfo() throws DataLoadException {
return null;
}
private final FutureTask<ProductInfo> future =
new FutureTask<ProductInfo>(new Callable<ProductInfo>() {
public ProductInfo call() throws DataLoadException {
return loadProductInfo();
}
});
private final Thread thread = new Thread(future);
public void start() { thread.start(); }
public ProductInfo get()
throws DataLoadException, InterruptedException {
try {
return future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof DataLoadException)
throw (DataLoadException) cause;
else
throw LaunderThrowable.launderThrowable(cause);
}
}
interface ProductInfo {
}
}
class DataLoadException extends Exception { }
- 同步工具类(闭锁,信号量,栅栏,FutureTask)
- 同步工具类闭锁,栅栏,信号量
- 同步工具类--闭锁、信号量、栅栏的总结
- 同步工具类--闭锁、信号量、栅栏的总结
- 闭锁/栅栏/信号量/FutureTask分析及使用
- 同步工具类--闭锁
- 同步工具类-闭锁
- java并发基础(二)--- Java监视器模型、并发容器、同步工具类(闭锁、信号量)
- 同步工具类-闭锁CountDownLatch
- 闭锁、栅栏、交换机、信号量学习笔记
- 同步工具类一:闭锁(java.util.concurrent.CountDownLatch)
- 同步工具类一:闭锁(java.util.concurrent.CountDownLatch)
- 闭锁、同步屏障、信号量详解
- Java同步工具类——闭锁
- 同步工具类之 FutureTask
- Synchronizer 闭锁(CountDownLatch,FutureTask ) 信号量(Semaphore) 关卡(CyclicBarrier) 知识点总结(java并发编程实践读书笔记三)
- Java同步工具类——FutureTask
- 同步容器类和工具类4——闭锁
- css背景图片的设置
- 解决ScrollView嵌套ListView和GridView冲突的方法
- 二叉树排序
- 删除全部binlog不影响数据库运行,类似Oracle的archivelog
- 为什么用Spring来管理Hibernate?
- 同步工具类(闭锁,信号量,栅栏,FutureTask)
- Ubuntu下查看CPU、内存和硬盘详细信息的几个命令
- 在oracle中,使用sqlldr将文件中的数据导入到数据库
- TCP/IP------协议头部
- HDOJ 献给杭电五十周年校庆的礼物
- 一些oracle知识
- 读取手机通讯录
- Linux内存管理(最透彻的一篇)
- ajax传送中文乱码