维护网址免费seo推广软件
一、Exchanger介绍
①、Exchanger,并发工具类,用于线程间的数据交换。
②、两个线程,两个缓冲区,一个线程往一个缓冲区里面填数据,另一个线程从另一个缓冲区里面取数据。当填数据的线程将缓冲区填满时,或者取数据的线程将缓冲区里的数据取空时,就主动向对方发起交换缓冲区的动作,而交换的时机是,一个缓冲区满,另一个缓冲区空。
注意:使用Exchanger来对线程进行数据操作时,线程必须是成对的(线程数量为双数)。
二、介绍Exchanger两个重要方法
①、exchange(V x):等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
package chapter3.exchanger;import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** @author czd*/
public class ExchangerTest1 {public static void main(String[] args) {final Exchanger<String> exchanger = new Exchanger<>();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {String result = exchanger.exchange(" 我是来自Thread-A发送的数据!");System.out.println(Thread.currentThread().getName() + " Result: " + result);}catch (InterruptedException e){e.printStackTrace();}}},"Thread-A").start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {TimeUnit.SECONDS.sleep(5);String result = exchanger.exchange(" 我是来自Thread-B发送的数据!");System.out.println(Thread.currentThread().getName() + " Result: " + result);}catch (Exception e){e.printStackTrace();}}},"Thread-B").start();}
}
输出结果
②、exchange(V x, long timeout, TimeUnit unit):等待另一个线程到达此交换点(除非当前线程被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。
package chapter3.exchanger;import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** @author czd*/
public class ExchangerTest1 {public static void main(String[] args) {final Exchanger<String> exchanger = new Exchanger<>();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {String result = exchanger.exchange(" 我是来自Thread-A发送的数据!",3,TimeUnit.SECONDS);System.out.println(Thread.currentThread().getName() + " Result: " + result);}catch (InterruptedException e){e.printStackTrace();} catch (TimeoutException e){System.out.println("超时了!");}}},"Thread-A").start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {TimeUnit.SECONDS.sleep(5);String result = exchanger.exchange(" 我是来自Thread-B发送的数据!");System.out.println(Thread.currentThread().getName() + " Result: " + result);}catch (Exception e){e.printStackTrace();}}},"Thread-B").start();}
}
输出结果
三、提出疑问–A:当使用Exchanger对两个线程进行数据交换时,线程A发送的东西,与线程B接收到的东西是否是一样的?(一样是指地址是否正确,而不仅仅是值一样)
下面是一个验证地址是否一样的代码案例
package chapter3.exchanger;import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;/*** @author czd*/
public class ExchangerTest2 {public static void main(String[] args) {final Exchanger<Object> exchanger = new Exchanger<>();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {Object object = new Object();Object obj = exchanger.exchange(object);System.out.println(Thread.currentThread().getName() + " Thread-A send Object: " + object);System.out.println(Thread.currentThread().getName() + " Thread-A get Object: " + obj);}catch (InterruptedException e){e.printStackTrace();}}},"Thread-A").start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");try {TimeUnit.SECONDS.sleep(5);Object object = new Object();Object obj = exchanger.exchange(object);System.out.println(Thread.currentThread().getName() + " Thread-B send Object: " + object);System.out.println(Thread.currentThread().getName() + " Thread-B get Object: " + obj);}catch (Exception e){e.printStackTrace();}}},"Thread-B").start();}
}
输出结果
由图可以看出,线程A发送的东西与线程B接收到的东西是一样的,即连地址都是一样的
四、提出疑问–B:当使用Exchanger对两个线程进行数据交换时,是不是只能交换一次?能否多次的对两个线程进行数据的交换?
下面是一个验证是否能多次进行数据交换的代码案例
package chapter3.exchanger;import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;/*** @author czd*/
public class ExchangerTest3 {public static void main(final String[] args) {final Exchanger<Integer> exchanger = new Exchanger<>();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");while (true){try {AtomicInteger atomicInteger = new AtomicInteger(1);atomicInteger.set(exchanger.exchange(atomicInteger.get()));System.out.println("Thread-A Value:" + atomicInteger.get());}catch (Exception e){e.printStackTrace();}}}},"Thread-A").start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "开始启动....");while (true){try {AtomicInteger atomicInteger = new AtomicInteger(2);atomicInteger.set(exchanger.exchange(atomicInteger.get()));System.out.println("Thread-B Value:" + atomicInteger.get());TimeUnit.SECONDS.sleep(2);}catch (Exception e){e.printStackTrace();}}}},"Thread-B").start();}
}
输出结果
由图可以看出,使用Exchanger可以对两个线程进行多次的数据交换