проблемы синхронизации в Java - PullRequest
0 голосов
/ 15 октября 2019

Может ли приведенный ниже код вызвать проблемы с синхронизацией?

Предполагается, что потоки совместно используют один объект Condition и получают блокировку Lock перед вызовом await () или signalAll ().

public class Condition {

    private Lock lock;
    private List<Thread> waitingThreads;

    /**
     * Create a condition variable associated with Lock lock.
     */
    Condition(Lock lock) {
        this.lock = lock;
        this.waitingThreads = new ArrayList<Thread>();
    }

    /**
     * Block on this condition variable.
     *
     * Requires the current thread to hold the Lock lock. Calling await() will
     * suspend the thread: it will make no further progress unless and until it
     * is resumed.
     */
    public void await() {
        waitingThreads.add(Thread.currentThread());
        lock.unlock();
        Thread.currentThread().suspend();
        lock.lock();
        waitingThreads.remove(Thread.currentThread());
    }

    /**
     * Signal all threads awaiting this condition.
     *
     * Requires the current thread to hold the Lock lock. Calling signalAll()
     * will resume all threads that suspend due to previous calls of await().
     */
    public void signalAll() {
        for (Thread thread : waitingThreads) {
            thread.resume();
        }
    }
}

1 Ответ

0 голосов
/ 15 октября 2019

Аспект синхронизации вашего класса выглядит хорошо.

Конечно, это предполагает, что предварительные условия выполнены;т. е. блокировка является , удерживаемой текущим потоком при вызове await() и signalAll().

Кроме того, мы должны предположить, что никакой другой код не изменяет ArrayList с помощью методов, непоказано или через отражение.

Однако у вашего Condition класса есть несколько дополнительных проблем:

  1. Методы suspend и resume, которыми вы являетесьиспользование устаревших и склонных к тупикам;см. Устаревший поток Java-потоков . Ссылка объясняет проблемы и описывает лучшие (более безопасные) альтернативы для обычных сценариев использования.

  2. Класс Condition, который вы нам показали, не дает возможности дляпоток для получения блокировки, но API утверждает, что поток должен удерживать блокировку при вызове await и signalAll.


Мне также неяснопочему ты это делаешьОбычные способы реализации условных переменных:

  • для использования примитивного мьютекса с Object::wait, Object::notify и / или Object::notifyAll или
  • для использования Lock и связанный Condition объект.

См. javadocs для Thread и Lock для подробностей и примеров.

Мне неизвестно о какой-либо производительности или других преимуществах использования Thread::suspend и Thread::resume по сравнению с другими способами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...