本文涉及到的代码可以在我的github中找到。
Exchanger(交换者)是一个用于线程间写作的工具类。它提供一个同步点,在这个同步点,2个线程可以交换彼此的数据。这2个线程通过exchange()方法交换数据。如果第一个线程执行exchange()方法,它会一直等待第二个线程也执行exchange()方法,当2个线程都到达同步点时,这2个线程就可以交换数据,将本线程产生的数据传递给对方。
Exchanger可以用于校对工作,比如人工录入银行电子账单流水,为了避免错误,采用AB2个人进行录入,录入到Excel之后,系统加载这2个Excel,并对2个账单数据进行校对。
下面是一个线程间交换数据的小Demo:
import java.util.concurrent.Exchanger;
public class ExchangerDemo
{
public static void main(String[] args)
{
Exchanger<String> intermediary = new Exchanger<>();
new Thread(new Runnable()
{
String data = "$1000";
@Override
public void run()
{
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName() + " say : I hava money: " + data + " , i want MAC");
try
{
String goods = (String) intermediary.exchange(data);// 这里进行交换,在这里等待,直到第二个线程执行exchange()方法
Thread.sleep((long) (Math.random() * 1000));
System.out.println(Thread.currentThread().getName() + " say :Now,I have : " + goods);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable()
{
String goods = "MAC";
@Override
public void run()
{
System.out.println(Thread.currentThread().getName() + " say : Yes,i have : " + goods);
try
{
String money = (String) intermediary.exchange(goods);// 与上面相同
Thread.sleep((long) (Math.random() * 1000));//
System.out.println(Thread.currentThread().getName() + " say: I get the " + money);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
运行结果:
Thread-0 say : I hava money: $1000 , i want MAC
Thread-1 say : Yes,i have : MAC
Thread-1 say: I get the $1000
Thread-0 say :Now,I have : MAC
对比上述代码,银行账单校对的代码很容易写出来。