【问题标题】:Java adding objects to a child thread's message queueJava将对象添加到子线程的消息队列
【发布时间】:2012-03-16 04:05:25
【问题描述】:

我有 2 个线程,它们通过消息队列进行通信。

如果我执行以下操作:

Messenger mess = new Messenger(); //Create an object of type Messenger
....
controller.enqueue(mess); //Adds it's reference to a message queue from another thread
....
mess = new Messenger(); //Create another object of type Messenger
....
controller.enqueue(mess); //Adds it's reference AS WELL to the message queue of another thread

我的问题是: 这行得通吗?来自控制器的消息队列中是否有 2 个对象? (实际上是对 2 个对象的 2 个引用)?还是只有一个,第二个?第二个对象创建是否会以某种方式覆盖第一个对象?

【问题讨论】:

  • 这完全取决于controller.enqueue() 的作用。阅读它的 javadoc。鉴于它的名字,我猜想 enqueue 将参数添加到队列中。而且“添加”并不意味着“替换最后一个元素”。但我只能猜测。
  • 实际上控制器是一个 Runnable 并且 enqueue 是我自己创建的消息队列类的方法。所以 enqueue 把它得到的对象放入一个 ArrayList
  • ArrayList.add() 确实将其参数添加到列表中。阅读它的 javadoc。
  • 如果你想使用带线程的工作队列,我会使用 ExecutorService。这是线程安全的、经过测试的、内置的,并为您提供了一个队列和一个线程池(可以只是一个)
  • 对不起,如果我的评论令人讨厌。但说真的,根本没有人能以你提出的形式回答你提出的问题。你看到了吗?所以问真的没意义!确实,在您对 A.H. 的回答的第一条评论中,您明确表示这个问题根本不是关于线程或队列的,而是关于 Java 中变量的基本行为。这本来是一个很好的问题。

标签: java multithreading instance message-queue


【解决方案1】:

enqueue 方法接收对两个不同对象的两个不同引用。如果该方法按照它的名称和类的名称所承诺的那样做,那么队列确实会有两个对象入队。

【讨论】:

  • 所以起初我从混乱中指向我的对象(信使)。然后我将它添加到消息队列中。现在我有两个变量指向同一个对象(mess var 和 queueu)?我用一个新的 Messenger 对象 (= new Messenger()) 覆盖了 mess 变量。所以现在我的队列指向我的第一个 Messenger 对象,而混乱指向第二个?
  • @AndreiBogdan 如果您的心理指令指针位于第三行“....”中:是的,您是正确的。
  • mess 是对消息的引用,而不是对象。当您传递 mess 时,您只传递您引用的对象,即每次都不是同一个对象,因为您正在更改引用。这是基本的 Java,与消息传递或多线程的工作方式无关。
  • 不太确定“心理指令指针”指的是什么,但没关系 :) 我想我明白了。谢谢你们。
  • 是的,我想是的。最好考虑 'mess' 在其值被推入队列后是无效的。上面调用“controller.enqueue”的线程实际上已经失去了对 Messenger 的所有权。事实上,如果您在入队后再次尝试引用它,您可能会发现消费者线程已将其出列、处理、取消其自己的引用变量、其内存已被 GC 并重新分配给其他对象。所以,一旦你入队,就创建另一个 - 第一个 enqueue() 和第二个 new() 之间不应该有点线。
猜你喜欢
  • 1970-01-01
  • 2014-11-20
  • 2015-09-27
  • 2011-03-13
  • 2011-03-25
  • 2017-06-10
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
相关资源
最近更新 更多