文档章节

Java并发编程中级篇(七):并发任务间交换数据

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/28 11:18
字数 1307
阅读 40
收藏 0

Java API提供了一个同步辅助类Exchanger。它允许你在线程执行过程中在线程之间交换数据。它的机制是在线程中设置通步点,当两个线程都到达同步点之时,它们交换数据结构,因此第一个线程的数据结构进入到第二个线程中,同时第二个线程的数据结构进入到第一个线程中。

Exchange应用局限于两个线程,所以我们可以使用Exchange来模拟只有一个生产者和一个消费者的生产者-消费者问题。

创建一个生产者线程类Producer,声明一个List<String>作为缓冲区,一个Exchange<List<String>>用来和消费者交换数据。线程的执行方法中,循环10次,每次向缓冲区中加入10个记录并调用Exchange.exchange(),方法来和消费者交换数据。最后打印缓冲区记录数和当前循环次数。

public class Producer implements Runnable {
    private List<String> buffer;
    private 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 < 10; i++) {
            System.out.printf("Producer: Cycle %d\n", cycle);
            for (int j = 0; j < 10; j++) {
                String message = "Event" + (i * 10 + j);
                System.out.printf("Producer: %s\n", message);
                buffer.add(message);
            }
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("Producer: %d\n", buffer.size());
            cycle++;
        }
    }
}

创建一个消费者线程类,同样声明一个数据缓冲区List<String>和一个Exchange用于和生产者交换数据。执行10次循环,每次循环使用exchanger.exchange()方法等待和生产者交换数据,交换数据成功后打印数据缓冲区的内容。

public class Consumer implements Runnable{
    private List<String> buffer;
    private 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 < 10; i++) {
            System.out.printf("Consumer: Cycle %d\n", cycle);
            try {
                buffer = exchanger.exchange(buffer);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.printf("Consumer: Buffer size %d\n", buffer.size());
            for(Iterator<String> iterator = buffer.iterator(); iterator.hasNext();) {
                String message = iterator.next();
                System.out.printf("Consumer: %s\n", message);
                iterator.remove();
            }
            cycle++;
        }
    }
}

创建主方法类,声明两个List<Stting>分别作为生产者和消费者的数据缓冲区,声明一个Exchanger对象用于在生产者线程和消费者线程之间交换数据。然后启动两个线程。

public class Main {
    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 threadP = new Thread(new Producer(buffer1, exchanger));
        Thread threadC = new Thread(new Consumer(buffer2, exchanger));

        threadP.start();
        threadC.start();
    }
}

查看控制台执行结果。执行开始后消费者线程持有一个空缓冲区,并等待和生产者线程在第一个同步点交换数据。生产者则向一个空的缓冲区中写入10条记录,然后再第一个同步点与消费者交换数据。在这个同步点上,消费者获得生产者的10条记录的缓存,生产者获得消费者的空缓存,所以你会看到消费者打印缓存中的10条记录,而生产者交换后的缓存数据量为0.

Producer: Cycle 1
Producer: Event0
Producer: Event1
Producer: Event2
Producer: Event3
Producer: Event4
Producer: Event5
Producer: Event6
Producer: Event7
Producer: Event8
Producer: Event9
Consumer: Cycle 1
Producer: 0
Producer: Cycle 2
Producer: Event10
Producer: Event11
Producer: Event12
Producer: Event13
Producer: Event14
Producer: Event15
Producer: Event16
Producer: Event17
Producer: Event18
Producer: Event19
Consumer: Buffer size 10
Consumer: Event0
Consumer: Event1
Consumer: Event2
Consumer: Event3
Consumer: Event4
Consumer: Event5
Consumer: Event6
Consumer: Event7
Consumer: Event8
Consumer: Event9
Consumer: Cycle 2
Consumer: Buffer size 10
Consumer: Event10
Consumer: Event11
Consumer: Event12
Consumer: Event13
Consumer: Event14
Consumer: Event15
Consumer: Event16
Consumer: Event17
Consumer: Event18
Consumer: Event19
Consumer: Cycle 3
Producer: 0
Producer: Cycle 3
Producer: Event20
Producer: Event21
Producer: Event22
Producer: Event23
Producer: Event24
Producer: Event25
Producer: Event26
Producer: Event27
Producer: Event28
Producer: Event29
Producer: 0
Producer: Cycle 4
Producer: Event30
Producer: Event31
Consumer: Buffer size 10
Consumer: Event20
Producer: Event32
Consumer: Event21
Consumer: Event22
Consumer: Event23
Producer: Event33
Consumer: Event24
Consumer: Event25
Consumer: Event26
Consumer: Event27
Consumer: Event28
Consumer: Event29
Consumer: Cycle 4
Producer: Event34
Producer: Event35
Producer: Event36
Producer: Event37
Producer: Event38
Producer: Event39
Producer: 0
Producer: Cycle 5
Producer: Event40
Consumer: Buffer size 10
Consumer: Event30
Consumer: Event31
Consumer: Event32
Consumer: Event33
Producer: Event41
Producer: Event42
Consumer: Event34
Producer: Event43
Consumer: Event35
Producer: Event44
Consumer: Event36
Producer: Event45
Consumer: Event37
Consumer: Event38
Consumer: Event39
Consumer: Cycle 5
Producer: Event46
Producer: Event47
Producer: Event48
Producer: Event49
Producer: 0
Producer: Cycle 6
Consumer: Buffer size 10
Consumer: Event40
Consumer: Event41
Producer: Event50
Consumer: Event42
Consumer: Event43
Consumer: Event44
Producer: Event51
Consumer: Event45
Producer: Event52
Consumer: Event46
Producer: Event53
Consumer: Event47
Producer: Event54
Producer: Event55
Producer: Event56
Producer: Event57
Producer: Event58
Producer: Event59
Consumer: Event48
Consumer: Event49
Consumer: Cycle 6
Consumer: Buffer size 10
Consumer: Event50
Consumer: Event51
Consumer: Event52
Consumer: Event53
Consumer: Event54
Consumer: Event55
Consumer: Event56
Consumer: Event57
Consumer: Event58
Consumer: Event59
Consumer: Cycle 7
Producer: 0
Producer: Cycle 7
Producer: Event60
Producer: Event61
Producer: Event62
Producer: Event63
Producer: Event64
Producer: Event65
Producer: Event66
Producer: Event67
Producer: Event68
Producer: Event69
Producer: 0
Producer: Cycle 8
Producer: Event70
Producer: Event71
Producer: Event72
Producer: Event73
Producer: Event74
Producer: Event75
Producer: Event76
Producer: Event77
Producer: Event78
Producer: Event79
Consumer: Buffer size 10
Consumer: Event60
Consumer: Event61
Consumer: Event62
Consumer: Event63
Consumer: Event64
Consumer: Event65
Consumer: Event66
Consumer: Event67
Consumer: Event68
Consumer: Event69
Consumer: Cycle 8
Consumer: Buffer size 10
Producer: 0
Producer: Cycle 9
Consumer: Event70
Producer: Event80
Consumer: Event71
Consumer: Event72
Producer: Event81
Consumer: Event73
Producer: Event82
Consumer: Event74
Consumer: Event75
Consumer: Event76
Producer: Event83
Consumer: Event77
Producer: Event84
Producer: Event85
Consumer: Event78
Consumer: Event79
Consumer: Cycle 9
Producer: Event86
Producer: Event87
Producer: Event88
Producer: Event89
Producer: 0
Producer: Cycle 10
Consumer: Buffer size 10
Consumer: Event80
Producer: Event90
Producer: Event91
Consumer: Event81
Producer: Event92
Consumer: Event82
Producer: Event93
Consumer: Event83
Producer: Event94
Consumer: Event84
Consumer: Event85
Consumer: Event86
Consumer: Event87
Consumer: Event88
Producer: Event95
Producer: Event96
Producer: Event97
Producer: Event98
Consumer: Event89
Consumer: Cycle 10
Producer: Event99
Producer: 0
Consumer: Buffer size 10
Consumer: Event90
Consumer: Event91
Consumer: Event92
Consumer: Event93
Consumer: Event94
Consumer: Event95
Consumer: Event96
Consumer: Event97
Consumer: Event98
Consumer: Event99

 

© 著作权归作者所有

阿拉德大陆的魔法师
粉丝 27
博文 91
码字总数 83019
作品 0
西城
程序员
私信 提问
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
661
1
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
718
1
Java线程面试题 Top 50

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者...

loda0128
2015/05/29
935
1
Java面试:投行的15个多线程和并发面试题

本文由ImportNew -一杯哈希不加盐 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,...

ImportNew
2018/08/23
0
0
读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
3.9K
8

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
10
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
1K
11
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部