public static void main(String[] args) { Semaphore semaphore = new Semaphore(2); ExecutorService executor = Executors.newFixedThreadPool(10); Runnable task = () -> { try { System.out.println(Thread.currentThread().getName() + " acquire before"); semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " acquire ok"); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } }; executor.execute(task); executor.execute(task); executor.execute(task); executor.execute(task);}
Exchanger 线程间交换数据Exchanger是一个用户线程间交换数据的工具类,它提供了一个同步点,在这个同步点上,两个线程可以交换彼此的数据 。这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange方法,他会一直等待第二个线程也执行exchange方法,当两个线程都达到同步点时,这两个线程交换数据,将本线程产生的数据传递给对方 。
public static void main(String[] args) { Exchanger<String> exchanger = new Exchanger<>(); Runnable task = () -> { try { String result = exchanger.exchange(Thread.currentThread().getName()); System.out.println(Thread.currentThread().getName() + ": " + result); } catch (InterruptedException e) { e.printStackTrace(); } }; ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(task); executor.execute(task);}
Exchanger实现分析Exchanger算法的核心是通过一个可交换数据的slot,以及一个可以带有数据item的参与者,slot是Node类型,Node定义如下:
@sun.misc.Contended static final class Node { int index; // Arena index int bound; // Last recorded value of Exchanger.bound int collides; // Number of CAS failures at current bound int hash; // Pseudo-random for spins Object item; // This thread's current item volatile Object match; // Item provided by releasing thread volatile Thread parked; // Set to this thread when parked, else null}static final class Participant extends ThreadLocal<Node> { public Node initialValue() { return new Node(); }}
每一个参与者都带有一个Participant,当调用exchange时,如果slot为空,则将自己携带的数据CAS设置到slot上,然后park自己;如果slot不为空,则表示已经有线程在slot里设置了数据,则读取Node.item字段,并将自己携带的数据设置到Node.match字段,然后唤醒之前设置数据的线程(之前阻塞的线程在唤醒后读取Node.match字段返回),然后返回数据即可 。
小结了解了这些Java并发工具类,小伙伴们在日常开发中,都用到哪种或者哪几种呢?
推荐阅读
- gradle:现代高效的java构建工具
- Go 并发编程的思考
- JavaScript?可视化:js引擎
- 10个 JavaScript 开发技巧,前端新手非常有必要掌握
- JetBrains 2020 年开发者生态系统状况报告,JAVA 最受欢迎的语言
- 快来学,那些关于燃气灶你不知道的事
- 淘宝创意标题怎么设置的 淘宝关于制作标题的注意事项
- Java类加载机制实现流程及原理详解
- 国内 Java 开发者必备的两个装备,你配置上了么?
- 关于头条号新版后台向万粉创作者开放内测的通知