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)

別のスレッドがどういうわけかキューから要素を削除したと思いますか? ロックしたのにどうしてそんなことができるの?

UPDATE : queue は実際にはArrayList<File>(). スレッドセーフでなくても問題ありませんか? 私はロックしましたqueueLockか?

4

1 に答える 1

1

あなたの特定の例に関して、queueLock とは何ですか? どこで作成されますか?スレッド間で共有されていますか (たとえば、静的 - 私の推測ではノーであり、問​​題を引き起こしている可能性があります)。詳細情報が必要です。

これらすべての質問について心配したくない場合は、synchronized を使用して書き直してください。よりシンプルに...

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 に答える