浅谈Java多线程(二)

7-21 2,531 views

线程的协调

在Java多线程中,对于线程之间共享的实例资源,可以通过synchronized修饰符修饰其方法,实现线程之间的同步。另外,在多线程设计中,还需考虑到线程之间的协调。关于协调的一个典型设计模式便是Producer-Consumer(生产者-消费者)模式。

Producer-Consumer(生产者-消费者)模式

在这一模式中,存在Producer和Consumer两类线程,Producer线程用于生成Data(共享数据资源),而Consumer线程用于消费Data,在Producer和Consumer之间,存在对于Data生成和消费的协调,即当不存在Data时,Consumer线程需要等待Producer线程生成新的Data,而当Data过多时,Producer线程需要等待Consumer线程消费过多的Data。在Producer-Consumer模式中,引入了Channel(管道)类,负责Data在各线程之间的协调。Producer-Consumer模式的UML类图如下所示。
152350862
在上图中,Producer线程类和Consumer线程类均包含对Channel类对象的引用,而Channel类对象封装了Data类,并分别实现了生产和消费Data的同步方法produce和consume。在produce和consume方法中,通过使用wait和notifyAll方法进一步实现Data的协调。

wait、notify、notifyAll

在Java中,wait、notify、notifyAll是Object类的方法,用于实现对调用对象方法的线程的暂停和唤醒。wait用于暂停线程,将其放入对象的wait set(线程等待集合),而notify、notifyAll方法用于唤醒wait set中的线程,使其继续执行。notify和notifyAll的不同是,当wait set中存在多个线程时,notify只会从中随机唤醒一个线程,而notifyAll会从中唤醒所有线程,由其进行竞争,获得同步锁并继续执行。
一个关于wait、notify、notifyAll使用的简单示例如图所示。
152640939

Producer-Consumer(生产者-消费者)模式的实现示例

Producer和Consumer线程类

Channel和Data类

主函数

执行结果

p2 is producing 0
c2 is consuming 0
p3 is producing 2
p1 is producing 1
c3 is consuming 2
c1 is consuming 1
p1 is producing 5
p3 is producing 4
c2 is consuming 5
p2 is producing 3
p3 is producing 7
c1 is consuming 4
c3 is consuming 3
p3 is producing 9
p1 is producing 6
c2 is consuming 7
p2 is producing 8
c3 is consuming 9
c1 is consuming 6
p2 is producing 12
p3 is producing 10
c2 is consuming 8
……

从执行结果中可以看出,生成Data线程的执行次数p和消费Data线程的执行次数c始终满足:

p>=c且p<=c+3

即保证Data数组在消费时存在Data但也不超过数组容量,从而有效实现Producer和Consumer线程类关于Data的协调。

总结

在Java多线程设计中,需要充分考虑线程之间的同步和协调。针对不同的应用场景,可以采用不同的设计模式,已有的设计模式有Single Threaded Execution、Immutable、Guarded Suspension、Balking、Producer-Consumer、Read-Write Lock、Thread-Per-Message、Worker Thread等,具体可进一步参考网上有关“Java多线程设计模式”的教程。

基于WebSocket实现微信小程序的消息推送

微信小程序支持通过基于WebSocket进行消息推送,提供了相应的API,例如创建连接示例代码: JavaScript wx.connectSocket({ ...

阅读全文

基于nginx-sticky-module-ng实现会话保持(Sticky Sessions)

对服务进行集群部署,前端进行负载均衡时,需要实现会话保持,对于同一会话的多个请求,通过集群中的一个节点来提供服务。系统的部署结构如图所示,通过Resin...

阅读全文

ActiveMQ基于Zookeeper和LevelDB实现Master/Slave

ActiveMQ的Master/Slave目前支持三种实现方式: 1)Shared File System Master Slave; 2)JDBC Master Slave; 3)Replicated LevelDB Store。 对于第三种方...

阅读全文