Java并发(十六):并发工具类——Exchanger

Exchanger(交换者)是一个用于线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。

举例

class ExchangerTest {

    static class Producer implements Runnable {

        // 生产者、消费者交换的数据结构
        private List<String> buffer;

        // 步生产者和消费者的交换对象
        private Exchanger<List<String>> exchanger;

        Producer(List<String> buffer, Exchanger<List<String>> exchanger) {
            this.buffer = buffer;
            this.exchanger = exchanger;
        }

        @Override
        public void run() {
            for (int i = 1; i < 5; i++) {
                for (int j = 1; j <= 3; j++) {
                    System.out.println("生产者装入" + i + "--" + j);
                    buffer.add("buffer:" + i + "--" + j);
                }

                System.out.println("生产者装满,等待与消费者交换...");
                try {
                    exchanger.exchange(buffer);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.err.println("生产者 " + i + ":" + buffer);
            }
        }
    }

    static class Consumer implements Runnable {
        private List<String> buffer;

        private final Exchanger<List<String>> exchanger;

        public Consumer(List<String> buffer, Exchanger<List<String>> exchanger) {
            this.buffer = buffer;
            this.exchanger = exchanger;
        }

        @Override
        public void run() {
            for (int i = 1; i < 5; i++) {
                // 调用exchange()与消费者进行数据交换
                try {
                    buffer = exchanger.exchange(buffer);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println("消费者第" + i + "次提取");
                for (int j = 1; j <= 3; j++) {
                    System.out.println("消费者 : " + buffer.get(0));
                    buffer.remove(0);
                }
            }
        }
    }

    public static void main(String[] args) {
        List<String> buffer1 = new ArrayList<String>();
        List<String> buffer2 = new ArrayList<String>();

        Exchanger<List<String>> exchanger = new Exchanger<List<String>>();

        Thread producerThread = new Thread(new Producer(buffer1, exchanger));
        Thread consumerThread = new Thread(new Consumer(buffer2, exchanger));

        producerThread.start();
        consumerThread.start();
    }
}

并发工具类(四)两个线程进行数据交换的Exchanger

【死磕Java并发】—–J.U.C之并发工具类:Exchanger

原文地址:https://www.cnblogs.com/hexinwei1/p/9984575.html

时间: 2024-08-02 12:05:06

Java并发(十六):并发工具类——Exchanger的相关文章

系统学习 Java IO (十六)----这么多类,应该用哪个?

目录:系统学习 Java IO---- 目录,概览 ### Java IO目的和功能 Java IO 包含 InputStream,OutputStream,Reader 和 Writer 类的许多子类. 原因是,所有这些子类都在解决各种不同的目的. 所涉及的目的总结如下: 网络访问 内部缓冲区访问 线程间通信(管道) 缓冲 过滤 解析 阅读和写作文本(Reader/Writer) 读写原始数据(long,int等) 读和写对象 Java IO类概述表 在讨论了 Java IO 类所针对的源,目

java中IO写文件工具类

下面是一些根据常用java类进行组装的对文件进行操作的类,平时,我更喜欢使用Jodd.io中提供的一些对文件的操作类,里面的方法写的简单易懂. 其中jodd中提供的JavaUtil类中提供的方法足够我们使用,里面的方法写的非常简练,例如append,read等方法,封装更好,更符合面向对象, 这里面我写的一些方法可多都是模仿jodd,从里面进行抽取出来的. /** * 获取路径文件夹下的所有文件 * @param path * @return */ public static File[] ge

Java随机取字符串的工具类

原文:Java随机取字符串的工具类 源代码下载地址:http://www.zuidaima.com/share/1550463479532544.htm Java 随机取字符串的工具类 可以全部是数字,字符,也可以字符和数字组合的工具类,希望能给大家带来帮助 package com.zuidaima.test; import java.util.Random; public class RandomUtils { public static final String ALLCHAR = "012

java实现发邮件的工具类,方便 好用(需要架包的Send Email To me)

原文:java实现发邮件的工具类,方便 好用(需要架包的Send Email To me) 源代码下载地址:http://www.zuidaima.com/share/1550463394794496.htm package com.zuidaima.util; import java.util.Properties; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.Multipart; impor

java HTML字符串正则表达式使用工具类

原文:java HTML字符串正则表达式使用工具类 代码下载地址:http://www.zuidaima.com/share/1550463453416448.htm HTML相关的正则表达式工具类 包括过滤HTML标记,转换HTML标记,替换特定HTML标记 package com.zuidaima.common.util; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p> * Title: H

Java 基于log4j的日志工具类

Java 基于log4j的日志工具类 对log4j日志类进行了简单封装,使用该封装类的优势在于以下两点: 1.不必在每个类中去创建对象,直接类名 + 方法即可 2.可以很方便的打印出堆栈信息 package com.tradeplatform.receiveorder.util; import java.io.PrintWriter; import java.io.StringWriter; import org.apache.log4j.Logger; /** * @Description 日

“全栈2019”Java第十六章:下划线在数字中的意义

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第十六章:下划线在数字中的意义 下一章 "全栈2019"Java第十七章:赋值运算符和算术运算符 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&q

“全栈2019”Java第九十六章:抽象局部内部类详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第九十六章:抽象局部内部类详解 下一章 "全栈2019"Java第九十七章:在方法中访问局部内部类成员详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学

【WPF学习】第二十六章 Application类——应用程序的生命周期

原文:[WPF学习]第二十六章 Application类--应用程序的生命周期 在WPF中,应用程序会经历简单的生命周期.在应用程序启动后,将立即创建应用程序对象,在应用程序运行时触发各种应用程序事件,你可以选择监视其中的某些事件.最后,当释放应用程序对象时,应用程序将结束. 一.创建Application对象 使用Application类的最简单方式是手动创建它.下面的示例演示了最小的程序:在应用程序入口(Main()方法)处创建名为MainWindow的窗口,并启动一个新的应用程序: 在本质