【问题标题】:Implementing a synchronized queue in Java using ArrayList使用 ArrayList 在 Java 中实现同步队列
【发布时间】:2013-01-04 12:24:31
【问题描述】:

我一直在做一个需要同步队列的项目,因为我的程序是多线程的,线程可能会访问这个队列。 我使用 arraylist 来做到这一点,但我似乎有一些问题并且线程陷入僵局。不知道是不是队列原因,只是想查一下:

public class URLQueue {
    private ArrayList<URL> urls;

    public URLQueue() {
        urls = new ArrayList<URL>();
    }

    public synchronized URL remove() throws InterruptedException {
        while (urls.isEmpty())
            wait();
        URL r = urls.remove(0);
        notifyAll();
        return r;
    }

    public synchronized void add(URL newURL) throws InterruptedException {
        urls.add(newURL);
        notifyAll();
    }

    public int getSize() {
        return urls.size();
    }
}

编辑: 即使在使用 LinkedBlockingQueue 时,我也会陷入与以前相同的循环中。我认为这是因为有一个线程正在等待队列被填满,但它从来没有因为其他功能已经完成运行......任何想法???

【问题讨论】:

  • 出于兴趣,为什么不使用专门为此目的设计的现有队列类?
  • 你为什么不使用Queue? Java 已经有很多该内置函数的实现。
  • 我会使用 ExecutorService,因为它将队列和线程池封装在一个中。有内置队列可以做你想做的事,但你甚至不需要直接使用它们。
  • 如果您遇到死锁,死锁发生在哪里,因为这是您应该查看的代码。使用调试器或 jstack 查看所有线程的状态,并找出死锁发生时它在做什么。
  • 我将循环 Queue 类并可能会使用它。谢谢!

标签: java arraylist synchronization queue


【解决方案1】:

最好在此处使用LinkedBlockingQueue,因为它是为此目的而设计的。在尝试删除元素时,它会一直等到某个元素可用。

LinkedBlockingQueue

它提供了一个take() 方法

检索并移除此队列的头部,如有必要,等待元素变为可用

【讨论】:

  • 虽然我的程序中使用了这个类,但我仍然陷入无限循环
  • 那我们需要看看你的代码,可能还有其他问题
  • 我已经编辑了我的帖子。如果您仍然需要代码,请告诉我
  • “因为有一个线程正在等待队列被填满”你不需要这个,你为什么要等待?
  • 如果一个线程试图从队列中取东西,而队列是空的,你建议我怎么办?等等……这是生产者-消费者系统
【解决方案2】:

在您的代码中,notifyAll() 不会引发 InterruptedException,因此您应该从 add() 中删除 throws

remove() 方法不需要notifyAll(),因为它的操作不应该唤醒其他线程。

getSize() 方法应该是同步的。

否则您的代码没有机会死锁,因为您需要 两个 锁来创建死锁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2012-01-23
    • 2013-11-02
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多