使用Exchanger进行两个线程之间的数据交互案例:
package com.dwz.utils; import java.util.concurrent.Exchanger; public class ExchangerExample1 { public static void main(String[] args) { Exchanger<String> exchanger = new Exchanger<String>(); new Thread(new Runnable() { @Override public void run() { try { String result = exchanger.exchange("I am from T-A."); System.out.println("aaaaaaa"); System.out.println(Thread.currentThread().getName() + " Get value [" + result + "]"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "end."); } }, "==A==").start(); new Thread(new Runnable() { @Override public void run() { try { String result = exchanger.exchange("I am from T-B."); Thread.sleep(10); System.out.println("BBBBBBBBB"); System.out.println(Thread.currentThread().getName() + " Get value [" + result + "]"); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "end."); } }, "==B==").start(); } }
测试结果:
aaaaaaa ==A== Get value [I am from T-B.] ==A==end. BBBBBBBBB ==B== Get value [I am from T-A.] ==B==end.
验证A、B线程交换的数据都是同一份,并不是数据对象的复制
package com.dwz.utils; import java.util.concurrent.Exchanger; /** * A、B线程交换的数据都是同一个,并不是对象的复制 */ public class ExchangerExample2 { public static void main(String[] args) { Exchanger<Object> exchanger = new Exchanger<Object>(); new Thread() { public void run() { Object aobj = new Object(); System.out.println("A will send the object " + aobj); try { Object robj = exchanger.exchange(aobj); System.out.println("A received the object" + robj); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread() { public void run() { Object bobj = new Object(); System.out.println("B will send the object " + bobj); try { Object robj = exchanger.exchange(bobj); System.out.println("B received the object" + robj); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } }
测试结果:
A will send the object java.lang.Object@5512a485
B will send the object java.lang.Object@28ec7f99
B received the objectjava.lang.Object@5512a485
A received the objectjava.lang.Object@28ec7f99
模拟一个A、B线程不断交换数据的场景
package com.dwz.utils; import java.util.concurrent.Exchanger; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * 模拟一个A、B线程不断交换数据的场景 */ public class ExchangerExample3 { public static void main(String[] args) { Exchanger<Integer> exchanger = new Exchanger<Integer>(); new Thread() { public void run() { AtomicReference<Integer> value = new AtomicReference<Integer>(1); try { while(true) { value.set(exchanger.exchange(value.get())); System.out.println("Thread A has value:" + value.get()); TimeUnit.SECONDS.sleep(3); } } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread() { public void run() { AtomicReference<Integer> value = new AtomicReference<Integer>(2); try { while(true) { value.set(exchanger.exchange(value.get())); System.out.println("Thread B has value:" + value.get()); TimeUnit.SECONDS.sleep(2); } } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); } }
测试结果:
Thread B has value:1 Thread A has value:2 Thread A has value:1 Thread B has value:2