java queue 清空_Java-并发清除列表

您上面的代码不是线程安全的.想象以下情况:

>在store.get()之后,线程A在add()处暂停

>线程B在processAndClear()中,替换列表,处理旧元素的所有元素,然后返回.

>线程A恢复,并将新项目添加到现在已过时的列表中,该列表将永远不会被处理.

这里可能最简单的解决方案是使用LinkedBlockingQueue,这也将大大简化任务:

class Store{

final LinkedBlockingQueue queue = new LinkedBlockingQueue<>();

void add(final Object o){

queue.put(o); // blocks until there is free space in the optionally bounded queue

}

void processAndClear(){

Object element;

while ((element = queue.poll()) != null) { // does not block on empty list but returns null instead

doSomething(element);

}

}

}

编辑:如何做到这一点与同步:

class Store{

final LinkedList queue = new LinkedList<>(); // has to be final for synchronized to work

void add(final Object o){

synchronized(queue) { // on the queue as this is the shared object in question

queue.add(o);

}

}

void processAndClear() {

final LinkedList elements = new LinkedList<>(); // temporary local list

synchronized(queue) { // here as well, as every access needs to be properly synchronized

elements.addAll(queue);

queue.clear();

}

for (Object e : elements) {

doSomething(e); // this is thread-safe as only this thread can access these now local elements

}

}

}

为什么这不是一个好主意

尽管这是线程安全的,但与并发版本相比要慢得多.假设您的系统中有100个线程经常调用add,而一个线程调用processAndClear.然后,将出现以下性能瓶颈:

>如果一个线程调用添加了其他99个线程调用,则同时搁置.

>在processAndClear的第一部分中,所有100个线程都被保留.

如果您假定这100个正在添加的线程没有其他事情要做,那么您可以轻松地证明,该应用程序的运行速度与单线程应用程序的运行速度相同,而没有同步成本.这意味着:100个线程的添加实际上要比1个线程慢.如果像第一个示例中那样使用并发列表,则情况并非如此.

但是,由于线程可以在旧元素上运行doSomething,而新元素可以添加,因此处理线程将获得较小的性能提升.但同样,并发示例可能会更快,因为您可能有多个线程同时进行处理.

也可以使用有效地同步,但是您将自动引入性能瓶颈,这可能导致应用程序以单线程运行的速度变慢,从而迫使您进行复杂的性能测试.此外,扩展功能总是存在引入线程问题的风险,因为锁定需要手动完成.与此相反,并发列表无需任何额外的代码即可解决所有这些问题,并且以后可以轻松更改或扩展代码.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值