1.实现原理
Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交换数据。因此该工具类的线程对象是成对的。
Exchanger类提供了两个方法,String exchange(V x):用于交换,启动交换并等待另一个线程调用exchange;String exchange(V x,long timeout,TimeUnit unit):用于交换,启动交换并等待另一个线程调用exchange,并且设置最大等待时间,当等待时间超过timeout便停止等待。
2.实例讲解
通过以上的原理,可以知道使用Exchanger类的核心便是exchange()方法的使用,接下来通过一个例子来使的该工具类的用途更加清晰。该例子主要讲解的是前段时间NBA交易截止日的交易。
-
-
import java.util.concurrent.Exchanger;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
-
public class ExchangerDemo {
-
-
public static void main(String[] args) {
-
ExecutorService executor = Executors.newCachedThreadPool();
-
-
final Exchanger exchanger = new Exchanger();
-
executor.execute(new Runnable() {
-
String data1 = "克拉克森,小拉里南斯";
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
-
executor.execute(new Runnable() {
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
executor.execute(new Runnable() {
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
executor.execute(new Runnable() {
-
String data1 = "以赛亚托马斯,弗莱";
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
-
-
-
private static void nbaTrade(String data1, Exchanger exchanger) {
-
-
System.out.println(Thread.currentThread().getName() + "在交易截止之前把 " + data1 + " 交易出去");
-
Thread.sleep((long) (Math.random() * 1000));
-
-
String data2 = (String) exchanger.exchange(data1);
-
System.out.println(Thread.currentThread().getName() + "交易得到" + data2);
-
} catch (InterruptedException e) {
-
-
-
-
运行程序,得到如下结果:
-
pool-1-thread-1在交易截止之前把 克拉克森,小拉里南斯 交易出去
-
pool-1-thread-2在交易截止之前把 格里芬 交易出去
-
pool-1-thread-3在交易截止之前把 哈里斯 交易出去
-
pool-1-thread-4在交易截止之前把 以赛亚托马斯,弗莱 交易出去
-
-
-
pool-1-thread-4交易得到克拉克森,小拉里南斯
-
pool-1-thread-1交易得到以赛亚托马斯,弗莱
以上例子可以看出两个都调用exchange()方法的线程会进行交换数据。接下来假设线程数目只有奇数个,观察情况:
如以下代码,将第四个线程注释掉。
-
-
import java.util.concurrent.Exchanger;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
-
public class ExchangerDemo {
-
-
public static void main(String[] args) {
-
ExecutorService executor = Executors.newCachedThreadPool();
-
-
final Exchanger exchanger = new Exchanger();
-
executor.execute(new Runnable() {
-
String data1 = "克拉克森,小拉里南斯";
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
-
executor.execute(new Runnable() {
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
executor.execute(new Runnable() {
-
-
-
-
-
nbaTrade(data1, exchanger);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
private static void nbaTrade(String data1, Exchanger exchanger) {
-
-
System.out.println(Thread.currentThread().getName() + "在交易截止之前把 " + data1 + " 交易出去");
-
Thread.sleep((long) (Math.random() * 1000));
-
-
String data2 = (String) exchanger.exchange(data1);
-
System.out.println(Thread.currentThread().getName() + "交易得到" + data2);
-
} catch (InterruptedException e) {
-
-
-
-
运行程序,得到如下结果:
-
pool-1-thread-1在交易截止之前把 克拉克森,小拉里南斯 交易出去
-
pool-1-thread-2在交易截止之前把 格里芬 交易出去
-
pool-1-thread-3在交易截止之前把 哈里斯 交易出去
-
-
由结果可知,线程2和线程3进行了交换数据,而线程1一直等待与它交换数据的线程调用exchange,但是只有3个线程,所以会一直等待。
因此,当两个线程之间出现数据交换的情况,可以使用Exchanger工具类实现数据交换。注意exchange方法的含义,以及触发数据交换的条件。
下面看代码例子:
package thread.exchanger;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExchangerTest {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();//线程缓存池
final Exchanger<String> exchanger = new Exchanger<String>();//用于一对线程的交换
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long)(Math.random()*10000));
String data1 = "白粉";
System.out.println("线程"+Thread.currentThread().getName()+"已经到达交换地点,准备拿"+data1+"交换!");
data1 = exchanger.exchange(data1);//进行交换返回交换后的物品
System.out.println("线程"+Thread.currentThread().getName()+"交换成功,拿到"+data1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long)(Math.random()*10000));
String data2 = "钱";
System.out.println("线程"+Thread.currentThread().getName()+"已经到达交换地点,准备拿"+data2+"交换!");
data2 = exchanger.exchange(data2);//进行交换返回交换后的物品
System.out.println("线程"+Thread.currentThread().getName()+"交换成功,拿到"+data2);
} catch (Exception e) {
e.printStackTrace();
}
}
});
pool.shutdown();
}
}
注意:exchanger只能用于一对或者一组线程的交换。交换的线程不能为奇数,否则会出现死锁等待。
- 大小: 7.5 KB
分享到:
相关推荐
Java线程与并发编程实践是Java开发者必备的技能之一,特别是在多核处理器和高并发应用环境中,有效地管理和利用线程能极大地提升程序的性能。本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,...
在Java编程中,多线程是并发编程的重要组成部分,它允许程序同时执行多个任务,从而提高了系统的效率和响应性。然而,在某些场景下,我们可能需要控制线程的执行顺序,确保它们按照特定的顺序交替运行,这在并发编程...
Java编程线程同步工具Exchanger的使用实例解析 Java编程线程同步工具Exchanger是Java编程语言中的一种线程同步工具,它提供了一种方便的方式来交换线程之间的信息。Exchanger类可以作为两个线程交换对象的同步点,...
Java线程是Java编程中的核心概念,它允许程序并发执行多个任务,提高系统资源的利用率,从而提升程序的效率和响应速度。Java线程的管理、同步和通信是每个Java开发者必须掌握的关键技能。 在Java中,线程的创建主要...
Java多线程编程中的Exchanger是一个非常有用的工具类,它位于`java.util.concurrent`包下,主要用于线程间的数据交换。Exchanger的核心功能是让两个线程在一个同步点相遇,进行数据交换。当一个线程调用`exchange`...
在深入探讨Java线程之前,我们首先需理解何为线程。线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以有多个线程,但至少有一个线程。在Java中,多线程编程是一...
Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,尽管Java程序员普遍了解线程的基础概念,但在项目实践中,尤其是在复杂场景下处理多线程...
Java中的`Exchanger`类是`java.util.concurrent`包的一部分,设计用于在多线程环境中进行数据交换。这个类提供了一个同步点,使得两个线程能够有效地传递它们各自的数据。`Exchanger`的核心功能在于它维护了两个槽位...
Java线程是Java程序的基础,它代表程序中的一条执行线索或线路。在Java中创建线程有两种传统方式,一种是通过继承Thread类并覆盖其run方法来创建线程;另一种是通过传递实现了Runnable接口的对象给Thread类的构造...
Exchanger是java 5引入的并发类,Exchanger顾名思义就是用来做交换的。这里主要是两个线程之间交换持有的对象。当Exchanger在一个线程中调用exchange方法之后,会等待另外的线程调用同样的exchange方法。 两个线程都...
4. **并发工具类**:java.util.concurrent包提供了多种并发工具,如Semaphore(信号量)、CountDownLatch(计数器)、CyclicBarrier(回环栅栏)和Exchanger(交换器),它们为多线程编程提供了更高级别的抽象和控制...
Java线程的生命周期主要包括以下五个阶段: - **新建(New)**:当使用`Thread`类的构造函数创建一个新的线程对象时,线程处于新建状态。 - **就绪(Runnable)**:调用线程的`start()`方法后,线程进入就绪状态,...
最后,我们还需要了解Java并发工具类,如Semaphore(信号量)、CountDownLatch(计数器)、CyclicBarrier(回环栅栏)和Exchanger(交换器),它们为多线程编程提供了强大的支持。 总结来说,Java多线程涉及的内容...
此外,Java 还提供了其他并发工具类,如 CountDownLatch、CyclicBarrier、Semaphore 和 Exchanger,它们在多线程编程中有着广泛的应用。 在实际开发中,合理地使用线程和并发控制可以提高系统的并发性能,但同时也...
Java提供了一些高级同步工具,如Semaphore(信号量)、CyclicBarrier(循环屏障)、CountDownLatch(倒计时锁)和Exchanger(交换器),它们提供了更灵活的线程同步方式。 四、线程池 Java的ExecutorService和...
4. **并发工具类**:Java并发包(java.util.concurrent)提供了丰富的工具类,如Semaphore(信号量)、CountDownLatch(倒计时器)、CyclicBarrier(回环屏障)和Exchanger(交换器)等。这些工具可以用来协调线程间的行为,...
4. **线程状态**:Java线程具有多种状态,例如NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(定时等待)和TERMINATED(终止)。 5. **同步机制**:在多线程编程中,同步是...
4. 线程状态:Java线程有五种状态,包括新建、就绪、运行、阻塞和终止。 二、并发与同步 1. 并发:多个线程在同一时间片内交替执行,宏观上看似同时运行。 2. 同步:控制多个线程对共享资源的访问,避免数据不...
Java多线程是Java编程中一个非常重要的概念,它允许程序同时执行多个任务,从而提高系统资源的利用率和程序的响应速度。在网络编程中,多线程技术的应用尤为广泛,可以处理并发请求、异步数据传输等复杂场景。在这个...
Java并发工具类是Java并发编程中的重要组成部分,其中包括了多种实用的工具,如CountDownLatch、Semaphore和Exchanger,这些工具类极大地简化了多线程环境下的同步和协调问题。 1. **CountDownLatch**: ...