同步器之Exchanger

类java.util.concurrent.Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据。每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程提供的数据,并返回。
当在运行不对称的活动时很有用,比如当一个线程填充了buffer,另一个线程从buffer中消费数据的时候,这两个线程可以用Exchanger来交换数据。当两个线程通过Exchanger交换数据的时候,这个交换对于两个线程来说是线程安全的。两个线程都会等到自己的程序运行到Exchanger这个地方时,进行等待。然后再进行数据交换,交换完毕后,各自进行以后的程序流程。

以下这个程序demo要做的事情就是生产者在交换前生产5个"生产者",然后再与消费者交换5个数据,然后再生产5个"交换后生产者",而消费者要在交换前消费5个"消费者",然后再与生产者交换5个数据,然后再消费5个"交换后消费者"。

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Exchanger;

/**
 * 两个线程间的数据交换
 *
 */
@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();
                }
            }
            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();
    }
}

运行结果:

生产者开始运行
开始生产数据
生产了第1个数据,耗时1秒
消费者开始运行
开始消费数据
消费了第1个数据
消费了第2个数据
消费了第3个数据
消费了第4个数据
消费了第5个数据
消费数据结束
开始与生产者交换数据
生产了第2个数据,耗时1秒
生产了第3个数据,耗时1秒
生产了第4个数据,耗时1秒
生产了第5个数据,耗时1秒
生产数据结束
开始与消费者交换数据
结束与消费者交换数据
生产者与消费者交换数据后,再生产数据
交换后生产了第6个数据,耗时1秒
消费者与生产者交换数据后,再消费数据
交换后消费了第6个数据
交换后生产了第7个数据,耗时1秒
交换后消费了第7个数据
交换后消费了第8个数据
交换后生产了第8个数据,耗时1秒
交换后消费了第9个数据
交换后生产了第9个数据,耗时1秒
开始遍历生产者交换后的数据
消费者1
消费者2
消费者3
消费者4
消费者5
交换后生产者6
交换后生产者7
交换后生产者8
交换后生产者9
开始遍历消费者交换后的数据
生产者1
生产者2
生产者3
生产者4
生产者5
交换后消费者6
交换后消费者7
交换后消费者8
交换后消费者9

 

posted @ 2012-06-14 16:28  一筐  阅读(459)  评论(0编辑  收藏  举报