如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到Exchanger这个类,Exchanger为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步点,只有当每个线程都在进入 exchange ()方法并给出对象时,才能接受其他线程返回时给出的对象。
Exchanger的构造方法如下:
[java]
Exchanger(); //创建一个新的 Exchanger。
Exchanger用到的主要方法有:
[java]
exchange(V x); //等待另一个线程到达此交换点(除非它被中断),然后将给定的对象传送给该线程,并接收该线程的对象。
exchange(V x, long timeout, TimeUnit unit); // 等待另一个线程到达此交换点(除非它被中断,或者超出了指定的等待时间),然后将给定的对象传送给该线程,同时接收该线程的对象。
下面是demo代码:
1 package com.xt.thinks21_7; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Random; 6 import java.util.concurrent.Exchanger; 7 import java.util.concurrent.TimeUnit; 8 9 public class ThreadLocalTest { 10 11 public static void main(String[] args) { 12 Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>(); 13 new Thread1(exchanger).start(); 14 new Thread2(exchanger).start(); 15 } 16 17 } 18 19 class Thread1 extends Thread { 20 List<Integer> list = new ArrayList<Integer>(); 21 Exchanger<List<Integer>> exchanger = null; 22 23 public Thread1(Exchanger<List<Integer>> exchanger) { 24 this.exchanger = exchanger; 25 } 26 27 @Override 28 public void run() { 29 Random rand = new Random(); 30 list.add(rand.nextInt(10000)); 31 list.add(rand.nextInt(10000)); 32 list.add(rand.nextInt(10000)); 33 list.add(rand.nextInt(10000)); 34 list.add(rand.nextInt(10000)); 35 System.out.println(" Thread1:list-->" + list.size() + " " + list); 36 for (int i = 0; i < 10; i++) { 37 try { 38 list = exchanger.exchange(list); 39 System.out.println(" Thread1:sizeoflist-->" + list.size() 40 + " " + list); 41 } catch (InterruptedException e) { 42 // TODO Auto-generated catch block 43 e.printStackTrace(); 44 } 45 } 46 } 47 } 48 49 class Thread2 extends Thread { 50 List<Integer> list = new ArrayList<Integer>(); 51 Exchanger<List<Integer>> exchanger = null; 52 53 public Thread2(Exchanger<List<Integer>> exchanger) { 54 this.exchanger = exchanger; 55 } 56 57 @Override 58 public void run() { 59 try { 60 TimeUnit.MILLISECONDS.sleep(10); 61 } catch (InterruptedException e1) { 62 // TODO Auto-generated catch block 63 e1.printStackTrace(); 64 } 65 Random rand = new Random(); 66 list.add(rand.nextInt(10000)); 67 list.add(rand.nextInt(10000)); 68 list.add(rand.nextInt(10000)); 69 list.add(rand.nextInt(10000)); 70 list.add(rand.nextInt(10000)); 71 System.out.println(" Thread2:list-->" + list.size() + " " + list); 72 for (int i = 0; i < 10; i++) { 73 try { 74 list = exchanger.exchange(list); 75 } catch (InterruptedException e) { 76 // TODO Auto-generated catch block 77 e.printStackTrace(); 78 } 79 System.out.println(" Thread2:sizeoflist-->" + list.size() + " " 80 + list); 81 } 82 } 83 }
输出结果:
Thread1:list-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:list-->5
[2774, 3676, 2137, 1446, 9944]
Thread2:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread1:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread2:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread1:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread1:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread2:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread1:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread1:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread1:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread2:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread1:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread1:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread2:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread1:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
Thread1:sizeoflist-->5
[5943, 3873, 5422, 2297, 3070]
Thread2:sizeoflist-->5
[2774, 3676, 2137, 1446, 9944]
从输出结果中可以看出两个线程互相交换数据,直到循环结束。