Java BlockingQueue在任何时候对所有线程都是一样的吗?

Java BlockingQueue在任何时候对所有线程都是一样的吗?,java,multithreading,locking,queue,Java,Multithreading,Locking,Queue,我正在实现一个程序,其中主线程将各种消息推送到工作线程,工作线程将工作结果推回到主线程 为此,我计划使用两个队列,一个用于推送到工作线程,另一个用于从中拉出 据我所知,线程缓存对象,因此,如果它们要将对象添加到另一个线程可以轮询的队列中,则此更改可能不会立即可见,也就是说,它可能不会同步。这是正确的吗 但是,如果我要使用一个阻塞队列,那么这个队列上的所有操作都应该对所有线程立即可见?这个答案假设您谈论的是线程安全的数据结构或构造。如果使用常规的非线程安全字段,则不能保证它会工作,但也不能保证它不

我正在实现一个程序,其中主线程将各种消息推送到工作线程,工作线程将工作结果推回到主线程

为此,我计划使用两个队列,一个用于推送到工作线程,另一个用于从中拉出

据我所知,线程缓存对象,因此,如果它们要将对象添加到另一个线程可以轮询的队列中,则此更改可能不会立即可见,也就是说,它可能不会同步。这是正确的吗


但是,如果我要使用一个
阻塞队列
,那么这个队列上的所有操作都应该对所有线程立即可见?

这个答案假设您谈论的是线程安全的数据结构或构造。如果使用常规的非线程安全字段,则不能保证它会工作,但也不能保证它不会工作。注意:这是线程安全的单元测试有用,但不是傻瓜式的

此更改可能不会立即可见,即可能无法同步。这是正确的吗

对。延迟通常在50-100纳秒的范围内,因此它可能几乎是即时的

该队列上的所有操作都应该对所有线程立即可见


这在真正的机器上是不可能的。您可以说的是,您永远不会因为可见性问题而出现错误,主要是非常轻微的延迟。(但是,由于它会产生垃圾,在最坏的情况下,如果机器没有进入休眠状态,则可以获得完整的GC延迟,在这种情况下,延迟可能是数小时或数天)

此答案假设您讨论的是线程安全的数据结构或构造。如果使用常规的非线程安全字段,则不能保证它会工作,但也不能保证它不会工作。注意:这是线程安全的单元测试有用,但不是傻瓜式的

此更改可能不会立即可见,即可能无法同步。这是正确的吗

对。延迟通常在50-100纳秒的范围内,因此它可能几乎是即时的

该队列上的所有操作都应该对所有线程立即可见


这在真正的机器上是不可能的。您可以说的是,您永远不会因为可见性问题而出现错误,主要是非常轻微的延迟。(但是,由于它会产生垃圾,在最坏的情况下,如果机器没有进入休眠状态,则可以获得完整的GC延迟,在这种情况下,延迟可能是数小时或数天)

此答案假设您讨论的是线程安全的数据结构或构造。如果使用常规的非线程安全字段,则不能保证它会工作,但也不能保证它不会工作。注意:这是线程安全的单元测试有用,但不是傻瓜式的

此更改可能不会立即可见,即可能无法同步。这是正确的吗

对。延迟通常在50-100纳秒的范围内,因此它可能几乎是即时的

该队列上的所有操作都应该对所有线程立即可见


这在真正的机器上是不可能的。您可以说的是,您永远不会因为可见性问题而出现错误,主要是非常轻微的延迟。(但是,由于它会产生垃圾,在最坏的情况下,如果机器没有进入休眠状态,则可以获得完整的GC延迟,在这种情况下,延迟可能是数小时或数天)

此答案假设您讨论的是线程安全的数据结构或构造。如果使用常规的非线程安全字段,则不能保证它会工作,但也不能保证它不会工作。注意:这是线程安全的单元测试有用,但不是傻瓜式的

此更改可能不会立即可见,即可能无法同步。这是正确的吗

对。延迟通常在50-100纳秒的范围内,因此它可能几乎是即时的

该队列上的所有操作都应该对所有线程立即可见

这在真正的机器上是不可能的。您可以说的是,您永远不会因为可见性问题而出现错误,主要是非常轻微的延迟。(但是,由于它会产生垃圾,因此在最坏的情况下,如果机器没有进入休眠状态,您可以获得完整的GC延迟,在这种情况下,延迟可能是数小时或数天)

对于
BlockingQueue
接口来说:

BlockingQueue
实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。”


因此,您可以保证1一个线程对队列所做的更改“立即”对其他线程可见。。。在记忆模型的意义上。处理
put
poll
调用的同步。(任何缓存效果都由javadoc中提到的机制处理。)

当然,这并不意味着它们都会看到语义层面的变化。这取决于线程调度之类的事情。(如果将一个对象添加到队列中,则只有一个线程能够将其删除。如果它在第二个线程看到队列状态之前执行此操作……无论出于何种原因……第二个线程都不会注意到添加了条目,然后又删除了条目。)

“立即”的粒度也未指定。例如,如果JVM只使用一个CPU/内核,那么线程只能在发出
put
调用的线程取消调度后(无论出于何种原因)从
poll
返回。此外,刷新内存缓存中的更改需要相当长的时间


1-这假设实现类满足“契约”。。。但是如果它没有,它就是有缺陷的。

对于
阻塞队列
接口来说:

BlockingQ