【问题标题】:Is this thread safe for two threads share on queue in java? [duplicate]这个线程对于java中队列上的两个线程共享是否安全? [复制]
【发布时间】:2013-08-15 12:36:28
【问题描述】:

我的Server 班级中有一个Queue

public class Server{

    Queue<Input> inputQueue; 

    public void start() {
      inThread = new InThread(inputQueue);
      outThread = new OutThread(inputQueue);

      inThread.start();
      outThread.start();
    }
}

inThread 负责在 inputQueue 中填入数据,outThread 负责从 outputQueue 中取出数据。 InThreadOutThread 将同时执行。数据是否有可能不是线程安全的?如果是这样,我做了一些研究,它有同步变量和同步方法。我应该使用哪一个?谢谢。

【问题讨论】:

    标签: java multithreading queue


    【解决方案1】:

    由于队列在线程之间共享,因此如果不同步读写方法,它就不是线程安全的。

    如果你想要一个现成的线程安全队列,那么你可以考虑使用 ConcurrentLinkedQueue:

    http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html

    【讨论】:

    • 如果提供链接,我会使用 Java 7 javadoc。
    【解决方案2】:

    虽然您现有的方法不是线程安全的,但手动同步的需求并不大。

    java.util.concurrent.ArrayBlockingQueue<E> 可以为您工作。它的构造函数允许传入一个集合,所以你可以这样做:

    ArrayBlockingQueue<Input>blockingQueue=new ArrayBlockingQueue<>(128, false, inputQueue);
    

    将 128 更改为容量,将布尔值更改为指定在块后排队是否应该公平。

    您也可以使用ConcurrentLinkedQueue。它的构造函数只是:

    ConcurrentLinkedQueue<Input> clq=new ConcurrentLinkedQueue<>(inputQueue);
    

    【讨论】:

    • 如果提供链接,我会使用 Java 7 javadoc。
    【解决方案3】:

    我会使用一个 ExecutorService,它包装了一个线程池和一个队列,并且是线程安全的/经过测试的/是为您编写的。

    你说得对,有些队列需要外部同步,但是如果你使用像 ConcurrentLinkedQueue 这样的线程安全集合,你就不需要同步,尽管这样做不会有太大的影响。

    【讨论】:

      【解决方案4】:

      对我来说,您的问题似乎是 standard producer consumer case with Wait and Notify 的情况。

      只要google一下java中的生产者消费者例子,你就会得到上千个例子。希望对你有所帮助。

      【讨论】:

      • 除非您必须使用 Java 1.3 或更早版本,否则我不会使用通知/等待。对于 Java 1.4+,我会使用并发库
      • 这不是一个好主意,也不鼓励仅链接的答案。
      猜你喜欢
      • 1970-01-01
      • 2011-08-02
      • 2012-12-26
      • 1970-01-01
      • 2013-12-13
      • 2015-06-17
      • 1970-01-01
      • 2018-07-14
      • 2016-03-10
      相关资源
      最近更新 更多