Exchanger示例

Exchanger有两个用户,当一(A)方调用exchange方法之后,就开始等待,直到另一(B)方开始调用exchange方法。两个exchange可以认为是原子性的。

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

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

        Producer producer = new Producer(buffer1, exchanger);
        Consumer consumer = new Consumer(buffer2, exchanger);

        Thread threadProducer = new Thread(producer);
        Thread threadConsumer = new Thread(consumer);
        threadProducer.start();
        threadConsumer.start();
    }
}
public class Producer implements Runnable {
    private List<String> buffer;
    private final Exchanger<List<String>> exchanger;

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

    @Override
    public void run() {
        int cycle = 1;
        for (int i = 0; i < 19; i++) {
            System.out.printf("Producer: Cycle %d\n", cycle);
            for (int j = 0; j < 8; j++) {
                String message = "Event " + ((i * 19) + j);
                System.out.printf("Producer: %s\n", message);
                buffer.add(message);
            }

            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Producer: " + buffer.size());
            cycle++;
        }
    }
}
public 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() {
        int cycle = 1;
        for (int i = 0; i < 19; i++) {
            System.out.printf("Consumer: Cycle %d\n", cycle);

            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.printf("Consumer: Cycle %d, total %d\n ", cycle, buffer.size());
            for (int j = 0; j < 8; j++) {
                String message = buffer.get(0);
                System.out.printf("Consumer: Cycle %d %s\n", cycle, message);
                buffer.remove(0);
            }
            cycle++;
        }

    }
}
时间: 2024-10-06 05:37:39

Exchanger示例的相关文章

[转载] java多线程学习-java.util.concurrent详解(二)Semaphore/FutureTask/Exchanger

转载自http://janeky.iteye.com/blog/770393 ----------------------------------------------------------------------------- 3. Semaphore     我们先来学习一下JDK1.5 API中关于这个类的详细介绍: “一个计数信号量.从概念上讲,信号量维护了一个许可集.如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可.每个 release() 添加一个许可,从

Java并发编程--6.Exchanger线程间交换数据

在两个线程之间定义同步点,当两个线程都到达同步点时,他们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,第二个线程的数据结构进入到第一个线程中 在生产者-消费者情境模式中它包含了一个数缓冲区,一个或者多个生产者,一个或者多个消费中 下面是生产者和消费者的示例: /** * 生产者和消费者交换数据 */ public class MyExchanger { public static void main(String[] args) { Exchanger<List<String>

java一些常用并发工具示例

最近把<java并发编程实战>-Java Consurrency in Practice 重温了一遍,把书中提到的一些常用工具记录于此: 一.闭锁(门栓)- CountDownLatch 适用场景:多线程测试时,通常为了精确计时,要求所有线程都ready后,才开始执行,防止有线程先起跑,造成不公平,类似时,所有线程执行完,整个程序才算运行完成. /** * 闭锁测试(菩提树下的杨过 http://yjmyzz.cnblogs.com/) * * @throws InterruptedExcep

Exchanger兄弟线程间数据信息交换

一.简述 Exchanger可以在两个线程之间交换数据,只能是2个线程,他不支持更多的线程之间互换数据.当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行. 二.代码示例 1 public class ExchangerTest { 2 3 public static void main(String[] args) { 4 Exchanger<String> exch

多线程并发常用类:condition,semaphore,CyclicBarrier,countdownlatch,exchanger使用整理

condition 类: 作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法.如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞:如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞.我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程.可以使用两个 Condition 实例来做到这一点. class BoundedBuff

Java并发编程--Exchanger

概述 用于线程间数据的交换.它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据.这两个线程通过exchange方法交换数据,如果第一个线程先执行exchange()方法,它会一直等待第二个线程也执行exchange方法,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方. Exchanger 可被视为 SynchronousQueue 的双向形式.Exchanger在遗传算法和管道设计等应用中很有用. 内存一致性:对于通过 Exchanger 成功交换对

并发工具类(四)线程间的交换数据 Exchanger

前言 ??JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了几个非常有用的并发工具类:CountDownLatch.CyclicBarrier.Semphore.Exchanger.Phaser: ??CountDownLatch.CyclicBarrier.Semphore.Phaser 这四个工具类提供一种并发流程的控制手段:而Exchanger工具类则提供了在线程之间交换数据的一种手段. 简介 ?? Exchanger的功能是使2个线程之间交换数据(有不少文章的说法是"传输数

JAVA多线程提高十一:同步工具Exchanger

Exchanger可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象.Exchanger 可能被视为 SynchronousQueue 的双向形式.Exchanger 可能在应用程序(比如遗传算法和管道设计)中很有用. 构造方法摘要  Exchanger() 创建一个新的 Exchanger. 方法摘要 CountDownLatch CyclicBarrier V exchange(V x) 等

25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方法,让主线程等待被join的线程执行完之后,主线程才能继续往下执行.当然,使用线程间消息通信机制也可以完成.其实,java并发工具类中为我们提供了类似"倒计时"这样的工具类,可以十分方便的完成所说的这种业务场景. 为了能够理解CountDownLatch,举一个很通俗的例子,运动员进行跑