java 1.5 多线程包_Java1.5 多线程新特性 Concurrent包分析

前言

在java 1.5之前,如果想实现多线程的一些操作,往往需要程序员自己来书写多线程的内容。这样会很痛苦,也很容易出现问题。但在自从1.5推出concurrent包后,多线程的书写将变得简单。我们有了一个非常好用的类库来实现多线程。Concurrent组成结构

该包的主要接口和类:

Executor:具体Runnable的执行者。

ExecutorService:一个线程池的管理者,有多种实现。比如:普通线程池,定时调度线程池。

Futurn:与线程交互的接口。用于获取接口实现后的结果。针对集合的优化

Concurrent包直接提供了一些针对多线程使用的集合优化,下面将对他们进行简要介绍。ConcurrentHashMap

Map的一个并发实现。在多线程情况下,他能够安全的运行,并有较高的效率。它支持并发读和写操作(默认情况下,可以支持16个的并发数量。在构造函数中可以修改)。

HashMap的实现是非线程安全的。在高并发情况下,使用get方法经常会发生死锁而且会导致cpu居高不下。所以在高并发状况下,不要使用HashMap。

Collection.synchronizedMap(new HashMap())相比, concurrentHashMap的效率会更高一些。BlockingQueue

BlockingQueue是一个接口,他实现了Queue。BlockingQueue是线程安全的,非常适合多个生产者和多个消费者线程之间传递数据。

抛出异常返回布尔值阻塞超时

插入Add(e)Offer(e)Put(e)Offer(e,time,unit)

移除Remove()Poll()Take()Poll(time,unit)

检查Element()Peek()

形象地理解,BlockingQueue好比有很多格子的传输带系统,不过当你(生产者)调用put方法的时候,如果有空闲的格子那么放入物体后立刻返回,如果没有空闲格子那么一直处于等待状态。add方法意味着如果没有空闲格子系统就会报警,然后如果处理该报警则按照你的意愿。offer方法优先于add方法,它通过返回true或flase来告诉你是否放入成功。offer超时方法,如果不空闲的情况下,尝试等待一段时间。

BlockingQueue有很多实现ArrayBlockingQueue,DelayQueue,LinkedBlockingDeque,LinkedBlockingQueue,PriorityBlockingQueue,SynchronousQueue

补充Dueue是个双向队列,可以当做堆栈来使用。BlockingQueue在ThreadPool中,作为任务队列来使用,用来保存没有立刻执行的工作任务对象。SynchronousQueue

SychronousQueue是BlockingQueue的一个实现,它看起来是一个队列,但是其实没有容量,是特定条件下的一个精简实现。

做个比喻,SychronousQueue对象就像一个接力棒,现在有两个运动员交棒者和接棒者(线程)要做交接。在交接点,交棒者没有交出之前是不能松开的(一种等待状态),接棒者在接到棒之前是必须等待。换一句话说不管谁先到交接点,必须处于等待状态。

在生产者和消费者模型中。如果生产者向SychronousQueue进行put操作,直到有另外的消费者线程进行take操作时才能返回。对消费者也是一样,take操作会被阻塞,直到生产者put。

在这种生产者-消费者模型下,生产者和消费者是进行手对手传递产品,在消费者消费一个产品之前,生产者必须处于等待状态。它给我们提供了在线程之间交换单一元素的极轻量级方法,并且具有阻塞语义。

提示:上面举例中有写局限性。其实生产者和消费者进程是可以任意数量的。M:N。生产线程之间会对SychronousQueue进行争用,消费者也是一样。

对SychronousQueue类似于其他语境中"会合通道"或"连接"点问题。它非常适合于传递性设计,在这种设计中,在一个线程中运行的对象要将某些信息、事件或任务传递给在另一个线程中运行的对象,它就必须与该对象同步。Exchanger

是SychronousQueue的双向实现。用来伙伴线程间交互对象。Exchanger可能在比如遗传算法和管道设计中很有用。

形象地说,就是两个人在预定的地方交互物品,任何一方没到之前都处于等待状态。

CopyOnWriteArrayList 和 CopyOnWriteArraySet

它们分别是List接口和Set接口的实现。正如类名所描述的那样,当数据结构发生变化的时候,会复制自身的内容,来保证一致性。大家都知道复制全部副本是非常昂贵的操作,看来这是一个非常不好的实现。事实上没有最好和最差的方案,只有最合适的方案。一般情况下,处理多线程同步问题,我们倾向使用同步的ArrayList,但同步也有其成本。

那么在什么情况下使用CopyOnWriteArrayList或者CopyOnWriteArraySet呢?数据量小。

对数据结构的修改是偶然发生的,相对于读操作。

举例来说,如果我们实现观察者模式的话,作为监听器集合是非常合适的。TimeUnit

Concurrent包里面的时间单位。省去了时间换算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值