java多线程编程——同步器Exchanger(四)
类java.util.concurrent.Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据。每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程提供的数据,并返回。
当在运行不对称的活动时很有用,比如当一个线程填充了buffer,另一个线程从buffer中消费数据的时候,这两个线程可以用Exchanger来交换数据。当两个线程通过Exchanger交换数据的时候,这个交换对于两个线程来说是线程安全的。两个线程都会等到自己的程序运行到Exchanger这个地方时,进行等待。然后再进行数据交换,交换完毕后,各自进行以后的程序流程。
以下这个程序demo要做的事情就是生产者在交换前生产5个"生产者",然后再与消费者交换5个数据,然后再生产5个"交换后生产者",而消费者要在交换前消费5个"消费者",然后再与生产者交换5个数据,然后再消费5个"交换后消费者"。
package test;import java.util.ArrayList;import java.util.Date;import java.util.Iterator;import java.util.List;import java.util.concurrent.Exchanger;/** * 两个线程间的数据交换 * * @author Administrator * */@SuppressWarnings("all")public class ExchangerDemo {private static final Exchanger ex = new Exchanger();class DataProducer implements Runnable {private List list = new ArrayList();public void run() {System.out.println("生产者开始运行");System.out.println("开始生产数据");for (int i = 1; i <= 5; i++) {System.out.println("生产了第" + i + "个数据,耗时1秒");list.add("生产者" + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("生产数据结束");System.out.println("开始与消费者交换数据");try {// 将数据准备用于交换,并返回消费者的数据list = (List) ex.exchange(list);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("结束与消费者交换数据");System.out.println("生产者与消费者交换数据后,再生产数据");for (int i = 6; i < 10; i++) {System.out.println("交换后生产了第" + i + "个数据,耗时1秒");list.add("交换后生产者" + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("开始遍历生产者交换后的数据");// 开始遍历生产者的数据for (Iterator iterator = list.iterator(); iterator.hasNext();) {System.out.println(iterator.next());}}}class DataConsumer implements Runnable {private List list = new ArrayList();public void run() {System.out.println("消费者开始运行");System.out.println("开始消费数据");for (int i = 1; i <= 5; i++) {System.out.println("消费了第" + i + "个数据");// 消费者产生数据,后面交换的时候给生产者list.add("消费者" + i);}System.out.println("消费数据结束");System.out.println("开始与生产者交换数据");try {// 进行数据交换,返回生产者的数据list = (List) ex.exchange(list);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("消费者与生产者交换数据后,再消费数据");for (int i = 6; i < 10; i++) {System.out.println("交换后消费了第" + i + "个数据");list.add("交换后消费者" + i);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("开始遍历消费者交换后的数据");for (Iterator iterator = list.iterator(); iterator.hasNext();) {System.out.println(iterator.next());}}}public static void main(String args[]) {ExchangerDemo et = new ExchangerDemo();new Thread(et.new DataProducer()).start();new Thread(et.new DataConsumer()).start();}}