public BlockingQueue<Message> Queue;
Queue = new LinkedBlockingQueue<>();
我知道是否使用了同步列表,我需要将其围绕在同步块中,以便在线程之间安全地使用它
阻塞队列是否一样?
答案 0 :(得分:2)
否,您不需要包围同步块。
从JDK javadocs ...
BlockingQueue实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来原子地实现其效果。但是,除非在实现中另外指定,否则批量Collection操作addAll,containsAll,retainAll和removeAll不一定是原子执行的。因此,例如,仅在c中添加一些元素之后,addAll(c)可能会失败(引发异常)。
仅需指出,根据我的经验,JDK的java.util.concurrent
包中的类不需要同步块。这些类为您管理并发,通常是线程安全的。无论是否有意,java.util.concurrent
似乎已取代了在现代Java代码中使用同步块的需求。
答案 1 :(得分:1)
根据用例,将说明两种可能需要同步块或不需要同步块的场景。
答案 2 :(得分:1)
您正在考虑将同步级别设置得太低。它与您使用的类无关。这是关于保护线程之间共享的数据和对象。
如果一个线程能够修改任何单个数据对象或一组相关数据对象,而其他线程能够同时查看或修改同一对象,则可能需要同步。原因是,在没有临时将数据置于无效状态的情况下,一个线程通常不可能以有意义的方式修改数据。
同步的目的是防止其他线程看到无效状态,并因此可能对相同数据或其他数据造成不良影响。
Java的Collections.synchronizedList(...)
为您提供了两个或多个线程共享List
的方式,以使列表本身不会受到以下行为的破坏:不同的线程。但是,它对List
中中的数据对象不提供任何保护。如果您的应用程序需要该保护,则由您自己提供。
如果您需要队列的等效保护,则可以使用实现java.util.concurrent.BlockingQueue
的多个类中的任何一个。但是要当心!同样的警告。队列本身将受到保护,以防损坏,但是保护不会自动扩展到线程通过队列传递的对象。