0

我有多个线程使用共享变量queue。处理它(打印)后,它从队列中删除元素

protected void tryToPrint() {
    while (true) {
        try {
            if (printer.isAvailable() && printer.isFair(this)) {
                queueLock.lock();
                try {
                    if (queue.isEmpty()) 
                        break;

                    printer.requestToPrint(this, queue.get(0));
                    queue.remove(0);
                    synchronized (System.out) {
                        System.out.println(getName() + " printed. queue size: " + queue.size());
                    }
                } finally {
                    queueLock.unlock();
                }
            } else {
                printer.requestToPrintNext(this);
            }
        } catch (IllegalPrintStateException e) {
            e.printStackTrace();
        }
    }
}

但我越来越

Exception in thread "Thread-1" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:604)
    at java.util.ArrayList.remove(ArrayList.java:445)
    at printer.ClientImpl.tryToPrint(ClientImpl.java:34)
    at printer.AbstractClient.run(AbstractClient.java:28)
    at java.lang.Thread.run(Thread.java:722)

我想另一个线程以某种方式从队列中删除了一个元素?我怎么可能通过我锁定它?

更新:队列实际上是一个ArrayList<File>(). 如果它不是线程安全的,这有关系吗?我确实锁定了queueLock

4

1 回答 1

1

关于您的具体示例,什么是 queueLock?它是在哪里创建的?它是否在线程之间共享(例如静态 - 我的猜测是否定的,这可能会导致您的问题)?需要更多信息。

如果您不想担心所有这些问题,那么只需使用同步重写它。更简单...

protected void tryToPrint() {
    while (true) {
        try {
            if (printer.isAvailable() && printer.isFair(this)) {
                synchronized(queue) {
                    if (queue.isEmpty()) 
                        break;

                    printer.requestToPrint(this, queue.get(0));
                    queue.remove(0);
                    synchronized (System.out) {
                        System.out.println(getName() + " printed. queue size: " + queue.size());
                    }
                }
            } else {
                printer.requestToPrintNext(this);
            }
        } catch (IllegalPrintStateException e) {
            e.printStackTrace();
        }
    }
}
于 2013-03-10T04:21:41.727 回答