多线程(七)并发集合

在前面的例子中,使用了guarded block和同步方法,在多个线程存取同共享对象FileArray时,防止出现线程间干扰。

(不熟悉guarded block和同步方法的同学,强烈建议先去看这个系列的前面几篇。)

 

实际上有更简便安全的方法,因为java提供了线程安全的并发集合对象(concurrent collections)。使用这些集合,可以自动实现线程安全,从而简化代码。

The java.util.concurrent package includes a number ofadditions to the Java Collections Framework. These are most easilycategorized by the collection interfaces provided:

  • BlockingQueue 定义了一个先进先出的数据结构。可以在试图向一个已满队列中再加入对象,或试图从一个空队列中取出时,实现阻塞或超时。

在前面的例子中,我们使用了wait和notifyall方法来实现 guarded block。而使用BlockingQueue则会自动实现。

注意BlockingQueue只是一个接口,而实现了这个接口的类有:

ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedTransferQueue, PriorityBlockingQueue, SynchronousQueue

BlockingQueue接口定义的不同的方法对于现在无法满足,但将来可能满足的条件有不同的响应:

比如调用add()方法向一个已满queue中添加element时,会抛出异常。调用offer()则会返回false。调用put()则会被阻塞,直到有空间放入element时放入。

java api这部分介绍比较详细,值得一看。

  • ConcurrentMap是java.util.Map的子接口,它提供了有用的原子操作。可以实现在一个map中存在一个key时,删除或覆盖key-value pair,或一个key不存在时添加key-value pair.

The standard general-purpose implementation ofConcurrentMap isConcurrentHashMap, which is a concurrent analog ofHashMap.想想在前面的例子中,为了防止scanner会重复向FileArray中存入同一个file,不得不使用重命名的方法:scanner将file放入FileArray时,会同时重命名文件为.upload。而scanner再次扫描目录时,会忽略.upload文件。而使用这个集合是不是就可以避免了呢?

实现了该接口的类是:ConcurrentHashMap, ConcurrentSkipListMap

  • ConcurrentNavigableMap 一个实现了模糊匹配的ConcurrentMap.The standard general-purpose implementation ofConcurrentNavigableMap isConcurrentSkipListMap, which is a concurrent analog of TreeMap.

实现了该接口的类是:ConcurrentSkipListMap

接下来,就使用concurrent collections来改写前面的例子。


对于前面的FTP传输文件的例子,可以使用BlockingQueue,但在scanner将file放入queue时,仍然需要重命名来防止重复放入。

而使用ConcurrentMap,可以将文件名中的关键信息作为key,并在该key不存在时才向map中添加,从而防止scanner重复放入文件。

改代码去了~~~

貌似很容易遇到ConcurrentModificationException。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值