JAVA线程14 - 新特性:同步工具
2014-03-05 16:23
309 查看
一、Semaphore
1. 简介
Semaphore实现信号量。Semaphore可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数。例如:实现一个文件允许的并发访问数。
单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了锁,再由另一个线程释放锁。这可应用于死锁恢复的一些场合。
2. 示例
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreTest { public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); final Semaphore sp = new Semaphore(3); for (int i = 0; i < 10; i++) { Runnable r = new Runnable() { @Override public void run() { try { sp.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程"+Thread.currentThread().getName()+"进入,当前已有并发"+(3-sp.availablePermits())); try { Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程"+Thread.currentThread().getName()+"即将离开"); sp.release(); System.out.println("线程"+Thread.currentThread().getName()+"已离开,当前已有并发"+(3-sp.availablePermits())); } }; es.execute(r); } es.shutdown(); } }
二、CyclicBarrier
1. 简介
障碍器。表示大家彼此等待,大家集合好后才开始出发,分散活动后又在指定地点集合碰面。2. 示例
import java.util.Date; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CyclicBarrierTest { public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); final CyclicBarrier cb = new CyclicBarrier(5); for (int i = 0; i < 5; i++) { Runnable r = new Runnable() { @Override public void run() { try { Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"到达目的地1,当前已到达"+(cb.getNumberWaiting()+1)+",正在等候"); cb.await(); System.out.println(new Date()+":所有线程已到达,向目的地2出发"); Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"到达目的地2,当前已到达"+(cb.getNumberWaiting()+1)+",正在等候"); cb.await(); System.out.println(new Date()+":所有线程已到达,向目的地3出发"); Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"到达目的地3,当前已到达"+(cb.getNumberWaiting()+1)+",正在等候"); cb.await(); System.out.println(new Date()+":所有线程已到达,任务结束"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; es.execute(r); } es.shutdown(); } }
三、CountDownLatch
1. 简介
犹如倒计时计数器,调用CountDownLatch对象的countDown()方法就将计数器-1,当计数器到达0时,则所有等待者或者单个等待着开始执行。2. 示例
import java.util.Date; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownLatchTest { public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); final CountDownLatch cdOrder = new CountDownLatch(1); final CountDownLatch cdAnswer = new CountDownLatch(5); for (int i = 0; i < 5; i++) { Runnable r = new Runnable() { @Override public void run() { try { //Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"准备接受命令"); cdOrder.await(); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"已接受命令"); Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"处理命令"); cdAnswer.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }; es.execute(r); } try { Thread.sleep(new Random().nextInt(10000)); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"即将发布命令"); cdOrder.countDown(); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"已发布命令,正等待结果"); cdAnswer.await(); System.out.println(new Date()+":线程"+Thread.currentThread().getName()+"已收到所有响应结果"); } catch (Exception e) { e.printStackTrace(); } es.shutdown(); } }
四、Exchanger
1. 简介
Exchanger用于两个线程之间的数据交换。每个线程在完成一定任务后想与对方交换数据,第一个先拿出数据的线程将一直等待第二个线程拿着数据的到来,才能彼此交换数据。2. 示例
import java.util.Date; import java.util.Random; import java.util.concurrent.Exchanger; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Exchanger交换机 两个线程之间用户交换数据 */ public class ExchangerTest { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); // 线程之间交换数据 final Exchanger exchanger = new Exchanger(); service.execute(new Runnable() { public void run() { try { String data = "【数据1】"; System.out.println(new Date()+":"+Thread.currentThread().getName() + "准备把" + data + "换出去"); Thread.sleep(new Random().nextInt(10000)); String data2 = (String) exchanger.exchange(data); System.out.println(new Date()+":"+Thread.currentThread().getName() + "换回的数据是" + data2); } catch (InterruptedException e) { e.printStackTrace(); } } }); service.execute(new Runnable() { public void run() { try { String data = "【数据2】"; System.out.println(new Date()+":"+Thread.currentThread().getName() + "准备把" + data + "换出去"); Thread.sleep(new Random().nextInt(10000)); String data2 = (String) exchanger.exchange(data); System.out.println(new Date()+":"+Thread.currentThread().getName() + "换回的数据是" + data2); } catch (Exception e) { e.printStackTrace(); } } }); } }
相关文章推荐
- java 分别利用synchronized和jdk1.5新特性实现多消费者-多生产者线程的等待唤醒机制
- 【Java并发编程】14、Thread,线程说明
- Java线程之1.5版新特性多生产者多消费者(四)
- JVM高级特性与实践(十三):线程实现 与 Java线程调度
- JAVA笔记14__多线程共享数据(同步)/ 线程死锁 / 生产者与消费者应用案例 / 线程池
- Java多线程-新特性-有返回值的线程
- 黑马程序员——java基础日记——多线程(2)——线程间通信与JDK1.5新特性
- java面试题14--进程和线程的差别
- Java并发14:并发三特性-可见性定义、可见性问题与可见性保证技术
- java基础(14)- 线程基础
- 关于java线程的一些特性 启动 中断 及如何退出
- javaSE_8系列博客——Java语言的特性(三)--类和对象(14)--初始化字段
- Java的一些高级特性(八)——Java7中的线程
- Java多线程-新特性-有返回值的线程
- 深入理解Java虚拟机JVM高级特性与最佳实践阅读总结—— 第十二章 Java内存模型与线程
- Java常用面试题14 如何暂停线程Sleep和Wait 你能分清楚吗?
- 黑马程序员_Java学习日记第四天-线程、Java1.5的新特性
- 14.Java本地线程(ThreadLocal)
- 菜鸟读JAVA²核心技术卷Ⅱ:高级特性(原书第7版)- 线程
- Java多线程-新特性-有返回值的线程