1.Exchanger

功能:用于线程间数据的交换

应用场景:1)遗传算法,目前还不是特别理解  2)校对工作,假设A,B线程做同一件任务,可以通过数据校验判断两线程是否正确的工作

例子:是一个简单的校对工作例子

  1. public class TestExchanger {
  2. public static void main(String[] args) {
  3. Exchanger<String> exchanger = new Exchanger<>();
  4. ExecutorService es = Executors.newFixedThreadPool(2); //拥有两个线程的线程池
  5. es.execute(new Runnable() {
  6. @Override
  7. public void run() {
  8. String A = "银行流水A";
  9. try {
  10. exchanger.exchange(A);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. });
  16.  
  17. es.execute(new Runnable() {
  18. @Override
  19. public void run() {
  20. String B = "银行流水B";
  21. try {
  22. String A = exchanger.exchange(B);
  23. System.out.println("A和B数据是否一致: " + A.equals(B) + ",A: " + A + ",B: " + B);
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. });
  29. }
  30. }

Exchanger类中最重要的一个方法就是exchange(),该方法用于交换信息,并且接受来自另外一个线程的数据,exchange()方法里面还可以加参数。exchange(V x,long timeout,TimeUnit unit)设置一个最大等待时间避免一直等待

注意:信息交换是在同步点(Exchager提供一个同步点)进行交换,而不是两个线程调用了exchange()方法就进行交换。

底层实现:Lock+Condition,暂时还没深入,学习了进行补充

2.Semaphore

功能:控制同时访问特定资源的线程数量

应用场景:流量控制,比如数据库的连接

例子:

  1. public class TestSemaphore {
  2. public static void main(String[] args) {
  3. // 线程池
  4. ExecutorService exec = Executors.newCachedThreadPool();
  5. //一次只能5个线程同时访问
  6. final Semaphore semp = new Semaphore(5);
  7. // 模拟20个客户端访问
  8. for (int index = 0; index < 20; index++) {
  9. final int NO = index;
  10. Runnable run = new Runnable() {
  11. public void run() {
  12. try {
  13. // 获取许可
  14. semp.acquire();
  15. System.out.println("Accessing: " + NO);
  16. Thread.sleep((long) (Math.random() * 10000));
  17. // 访问完后,释放
  18. semp.release();
  19. System.out.println("-----------------"+semp.availablePermits());
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23.  
  24. }
  25.  
  26. };
  27. exec.execute(run);
  28. }
  29.  
  30. // 退出线程池
  31. exec.shutdown();
  32.  
  33. }
  34. }

同时有五个线程可以执行,获取资源后打印语句后随机睡眠,最后释放资源,semp.availablePermits(),可以获得的许可数量,释放一个后将有一个没有被分发的许可证,当有多的许可证时,会采取先到先得的方式分配许可

Semaphore有两个构造函数,Semaphore(int)和Semaphore(int,boolean)。参数中的int表示该信号量拥有的许可数量,boolean表示获取许可的时候是否是公平的,如果是公平的那么,当有多个线程要获取许可时,会按照线程来的先后顺序分配许可,否则,线程获得许可的顺序是不定的

3.CyclicBarrier

功能:控制同时访问特定资源的线程数量

应用场景:希望创建一组任务,并行执行,在进行下一个步骤之前等待,直到所有任务完成

例子:赛马比赛。只有当所有马一起到达栅栏时,才能继续跑下一个栅栏

Horse类:

  1. public class Horse implements Runnable {
  2. private static int counter = 0;
  3. private final int id = counter++;
  4. private int strides = 0;
  5. private static Random rand = new Random(47);
  6. private static CyclicBarrier barrier;
  7. public Horse(CyclicBarrier b) { barrier = b; }
  8. public synchronized int getStrides() { return strides; }
  9. public void run() {
  10. try {
  11. while(!Thread.interrupted()) {
  12. synchronized(this) {
  13. strides += rand.nextInt(3); // Produces 0, 1 or 2
  14. }
  15. barrier.await(); //在栅栏处等待
  16. }
  17. } catch(InterruptedException e) {
  18. // A legitimate way to exit
  19. } catch(BrokenBarrierException e) {
  20. // This one we want to know about
  21. throw new RuntimeException(e);
  22. }
  23. }
  24. public String toString() { return "Horse " + id + " "; }
  25. public String tracks() {
  26. StringBuilder s = new StringBuilder();
  27. for(int i = 0; i < getStrides(); i++)
  28. s.append("*");
  29. s.append(id);
  30. return s.toString();
  31. }
  32. }

HorseRace类:

  1. public class HorseRace {
  2. static final int FINISH_LINE = 75;
  3. private List<Horse> horses = new ArrayList<Horse>();
  4. private ExecutorService exec =
  5. Executors.newCachedThreadPool();
  6. private CyclicBarrier barrier;
  7. public HorseRace(int nHorses, final int pause) {
  8. barrier = new CyclicBarrier(nHorses, new Runnable() {
  9. public void run() {
  10. System.out.println("执行runnable方法的线程: " + Thread.currentThread().getName());
  11. StringBuilder s = new StringBuilder();
  12. for(int i = 0; i < FINISH_LINE; i++)
  13. s.append("="); // The fence on the racetrack
  14. System.out.println(s);
  15. for(Horse horse : horses)
  16. System.out.println(horse.tracks());
  17. for(Horse horse : horses)
  18. if(horse.getStrides() >= FINISH_LINE) {
  19. System.out.println(horse + "won!");
  20. exec.shutdownNow();
  21. return;
  22. }
  23. try {
  24. TimeUnit.MILLISECONDS.sleep(pause);
  25. } catch(InterruptedException e) {
  26. System.out.println("barrier-action sleep interrupted");
  27. }
  28. }
  29. });
  30.  
  31. for(int i = 0; i < nHorses; i++) {
  32. Horse horse = new Horse(barrier);
  33. horses.add(horse);
  34. exec.execute(horse);
  35. }
  36. }
  37.  
  38. public static void main(String[] args) {
  39. int nHorses = 7;
  40. int pause = 200;
  41.  
  42. new HorseRace(nHorses, pause);
  43. }
  44. }

CyclicBarrier有两个构造函数:

  1. public CyclicBarrier(int parties, Runnable barrierAction) {}
  2. public CyclicBarrier(int parties) {}

parties代表一次要并行执行的任务,barrierAction当这些线程都到达barries状态时要执行的任务,会选择一个线程去启动这个任务

重载方法await()

  1. public int await() throws InterruptedException, BrokenBarrierException { }
  2. public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { }

第一个方法用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务。第二个方法是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务

4.CountDownLatch

功能:允许一个或多个线程等待其他线程完成操作

应用场景:

例子:

  1. public class TestCountDown {
  2. private static CountDownLatch c = new CountDownLatch(2); //等待线程的执行数量为2
  3. public static void main(String[] args) throws InterruptedException {
  4. new Thread(
  5. new Runnable() {
  6. @Override
  7. public void run() {
  8. System.out.println(1);
  9. c.countDown();
  10. }
  11. }
  12. ).start();
  13.  
  14. new Thread(new Runnable() {
  15. @Override
  16. public void run() {
  17. System.out.println(2);
  18. c.countDown();
  19. }
  20. }).start();
  21.  
  22. c.await(); //阻塞当前线程,即main线程等待其他线程完成任务以后才能执行
  23. System.out.println(3);
  24. }
  25.  
  26. }

java并发包下的并发工具类的更多相关文章

  1. Java中的4个并发工具类 CountDownLatch CyclicBarrier Semaphore Exchanger

    在 java.util.concurrent 包中提供了 4 个有用的并发工具类 CountDownLatch 允许一个或多个线程等待其他线程完成操作,课题点 Thread 类的 join() 方法 ...

  2. 【Java并发工具类】Java并发容器

    前言 Java并发包有很大一部分都是关于并发容器的.Java在5.0版本之前线程安全的容器称之为同步容器.同步容器实现线程安全的方式:是将每个公有方法都使用synchronized修饰,保证每次只有一 ...

  3. 【Java并发工具类】Semaphore

    前言 1965年,荷兰计算机科学家Dijkstra提出的信号量机制成为一种高效的进程同步机制.这之后的15年,信号量一直都是并发编程领域的终结者.1980年,管程被提出,成为继信号量之后的在并发编程领 ...

  4. Java并发编程-并发工具类及线程池

    JUC中提供了几个比较常用的并发工具类,比如CountDownLatch.CyclicBarrier.Semaphore. CountDownLatch: countdownlatch是一个同步工具类 ...

  5. Java并发—并发工具类

    在JDK的并发包里提供了几个非常有用的并发工具类.CountDownLatch.CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段,Exchanger工具类则提供了在线程 ...

  6. JAVA并发工具类---------------(CountDownLatch和CyclicBarrier)

    CountDownLatch是什么 CountDownLatch,英文翻译为倒计时锁存器,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进 ...

  7. 《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类

    第6章 Java并发容器和框架 6.1  ConcurrentHashMap(线程安全的HashMap.锁分段技术) 6.1.1 为什么要使用ConcurrentHashMap 在并发编程中使用Has ...

  8. java多线程10:并发工具类CountDownLatch、CyclicBarrier和Semaphore

    在JDK的并发包(java.util.concurrent下)中给开发者提供了几个非常有用的并发工具类,让用户不需要再去关心如何在并发场景下写出同时兼顾线程安全性与高效率的代码. 本文分别介绍Coun ...

  9. java 并发工具类CountDownLatch & CyclicBarrier

    一起在java1.5被引入的并发工具类还有CountDownLatch.CyclicBarrier.Semaphore.ConcurrentHashMap和BlockingQueue,它们都存在于ja ...

随机推荐

  1. PhiloGL学习(1)——场景创建及方块欲露还羞出水面

    前言 上一篇文章中介绍了我认识PhiloGL框架的机缘以及初步的探讨(见JS前端三维地球渲染--中国各城市航空路线展示),在此文中仅仅对此框架进行了简单介绍并初步介绍了一些该框架的知识.首先三维这个东 ...

  2. LeetCode 476. Number Complement (数的补数)

    Given a positive integer, output its complement number. The complement strategy is to flip the bits ...

  3. LeetCode 252. Meeting Rooms (会议室)$

    Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...

  4. React UI 组件库uiw v1.2.8 发布

    uiw 高品质的UI工具包,基于React 16+的组件库.

  5. 在webapi中为Action使用dynamic参数实现Post方式调用

    1.在webapi中使用controller/action/id的路径配置,打开文件[App_Start] -[WebApiConfig] config.Routes.MapHttpRoute( na ...

  6. swift之函数式编程(二)

    本文的主要内容来自<Functional Programming in Swift>这本书,有点所谓的观后总结 在本书的Introduction章中: we will try to foc ...

  7. css是如何实现在页面文字不换行、自动换行、强制换行的

    强制不换行 div{ white-space:nowrap; } 自动换行 div{ word-wrap: break-word; word-break: normal; } 强制英文单词断行 div ...

  8. input file选择图片后 预览

    很多前端都选择用插件来实现图片预览,这个小功能也可以很简单的用jQuery来实现 简单的jQuery实现input file选择图片后,可以预览图片的效果 简单的HTML代码: <div> ...

  9. Python Web框架篇:Django Form组件

    Form简介 在HTTP中,表单(form标签),是用来提交数据的,其action属性说明了其传输数据的方法:如何传.如何接收. 访问网站时,表单可以实现客户端与服务器之间的通信.例如查询,就用到了表 ...

  10. linux学习(八)chmod、chown、umask、lsattr、chattr

    一.权限位 权限位分为两个部分,第一个部分是谁的权限,第二部分是权限是多少.其中第一个部分一般分为:用户,用户组,其他用户.第二部分分为r:读权限,w:写权限,x:执行权限.可读,可写,可执行的权限, ...