zoukankan      html  css  js  c++  java
  • Java:多线程,Exchanger同步器

    1. 背景

    类java.util.concurrent.Exchanger提供了一个同步点,在这个同步点,一对线程可以交换数据。每个线程通过exchange()方法的入口提供数据给他的伙伴线程,并接收他的伙伴线程提供的数据,并返回。

    当在运行不对称的活动时很有用。比如说,一个线程向buffer中填充数据,另一个线程从buffer中消费数据;这些线程可以用Exchange来交换数据。这个交换对于两个线程来说都是安全的。

    2. 示范代码

    package com.clzhang.sample.thread;
    
    import java.util.*;
    import java.util.concurrent.Exchanger;
    
    public class SyncExchanger {
        private static final Exchanger exchanger = new Exchanger();
    
        class DataProducer implements Runnable {
            private List list = new ArrayList();
    
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("生产了一个数据,耗时1秒");
                    list.add(new Date());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
                try {
                    list = (List) exchanger.exchange(list);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                    System.out.println("Producer " + iterator.next());
                }
            }
        }
    
        class DataConsumer implements Runnable {
            private List list = new ArrayList();
    
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    list.add("这是一个收条。");
                }
    
                try {
                    list = (List) exchanger.exchange(list);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                    Date d = (Date) iterator.next();
                    System.out.println("Consumer: " + d);
                }
            }
        }
    
        public static void main(String[] args) {
            SyncExchanger ins = new SyncExchanger();
            new Thread(ins.new DataProducer()).start();
            new Thread(ins.new DataConsumer()).start();
        }
    }

    输出
    生产了一个数据,耗时1秒
    生产了一个数据,耗时1秒
    生产了一个数据,耗时1秒
    生产了一个数据,耗时1秒
    生产了一个数据,耗时1秒
    Producer 这是一个收条。
    Producer 这是一个收条。
    Producer 这是一个收条。
    Producer 这是一个收条。
    Producer 这是一个收条。
    Consumer: Thu Sep 12 17:21:39 CST 2013
    Consumer: Thu Sep 12 17:21:40 CST 2013
    Consumer: Thu Sep 12 17:21:41 CST 2013
    Consumer: Thu Sep 12 17:21:42 CST 2013
    Consumer: Thu Sep 12 17:21:43 CST 2013

  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/nayitian/p/3317384.html
Copyright © 2011-2022 走看看