为了账号安全,请及时绑定邮箱和手机立即绑定

LinkedBlockingQueue 和工作线程 - 这段代码线程安全吗?

LinkedBlockingQueue 和工作线程 - 这段代码线程安全吗?

至尊宝的传说 2023-11-10 16:24:48
我试图了解下面的内容是否是线程安全的,它是由另一位开发人员编写的,我继承了该开发人员的代码,但不再属于我们。我有一个 BaseProvider 类,它实际上是一个消息缓存,由 LinkedBlockingQueue 表示。此类将传入消息存储在队列中。我有一组读取该队列的工作线程。因此 LinkedBlockingQueue 是线程安全的。问题 1. 当工作线程调用provider.getNextQueuedItem()时,提供者逐项遍历并将其添加到列表中并返回消息列表。在执行此操作时,如果通过调用 addToQueue 将消息添加到提供者类中,会发生什么情况?LinkedBlockingQueue 内部的 takeLock 是否会阻止向队列添加新消息,直到所有消息都从队列中取出?您会注意到,每个工作线程都可以访问所有提供程序,因此当一个工作线程遍历所有提供程序并调用 getNextQueuedItem() 时,当另一个工作线程也调用所有提供程序并调用 getNextQueuedItem() 时会发生什么?两个工作线程会互相跨过吗?公共抽象类 BaseProvider 实现 IProvider { private LinkedBlockingQueue<CoreMessage> internalQueue = new LinkedBlockingQueue<CoreMessage>();@Overridepublic synchronized List<CoreMessage> getNextQueuedItem() {    List<CoreMessage> arrMessages = new ArrayList<CoreMessage>();                        if (internalQueue.size() > 0) {        Logger.debug("Queue has entries");            CoreMessage msg = null;        try {            msg = internalQueue.take();        } catch (InterruptedException e) {            Logger.warn("Interruption");            e.printStackTrace();        }        if (msg != null) {            arrMessages.add(msg);        }    }    return arrMessages;}protected synchronized void addToQueue(CoreMessage message) {    try {        internalQueue.put(message);    } catch (InterruptedException e) {        Logger.error("Exception adding message to queue " + message);    }}}
查看完整描述

1 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

如果通过调用 addToQueue 将消息添加到提供者类中会发生什么?

getNextQueuedItem()addToQueue(...)都是synchronized方法。如果这是唯一访问 的两个方法private ... internalQueue,那么多个线程就无法同时访问internalQueue

当一个工作线程正在遍历所有提供程序并调用 getNextQueuedItem() 时,当另一个工作线程也调用所有提供程序并调用 getNextQueuedItem() 时,会发生什么情况?

您是否询问多个工作人员访问同一提供商?这是不可能发生的,因为getNextQueuedItem()这是一种synchronized方法。

- 或者 -

您是否询问不同的工作人员访问不同的提供商?这应该不重要(至少,就类而言BaseProvider),因为似乎没有任何方式可以将不同的对象相互连接起来。


查看完整回答
反对 回复 2023-11-10
  • 1 回答
  • 0 关注
  • 126 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信