Вопрос

У меня есть фрагмент кода, который я просматриваю (используя Найти ошибки).

public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;

public boolean testMethod(){
    boolean done = false;
    synchronized(q){
       if(q.size == batchSize){
         q.notify();
         done = true;
       }
    }
    return done;

}

Когда я запускаю FindBugs для этого фрагмента кода, он жалуется, что -

Этот метод выполняет синхронизацию объекта, который является экземпляром класса из пакета java.util.concurrent (или его подклассов).Примеры этих классов имеют собственные механизмы управления параллелизмом, которые отличаются от и несовместимы с использованием синхронизированного ключевого слова.

Если я закомментирую синхронизированный фрагмент кода synchronized(q){, оно жалуется -

Этот метод вызывает object.notify () или object.notifyall (), не удерживая блокировку на объекте.Вызов notify () или notifyall () без удержания блокировки приведет к тому, что нелегаламонгартатейтэкспрессия брошено

Как мне реализовать этот метод, чтобы он прошел проверку FindBugs?Подходит ли приведенная выше реализация для уведомления в случаях параллельных классов?

Спасибо.

Это было полезно?

Решение

notify() идет вместе с wait() и не должен использоваться с классами java.util.concurrent.

BlockingQueue использует внутренние механизмы для блокировки put() если нет места для дополнительных элементов или на poll() если нет элемента для потребления.Вам не нужно об этом заботиться.

Другие советы

Первая ошибка заключается в том, что вы не должны использовать примитивные элементы управления синхронизацией в классах java.util.concurrent (например, BlockingQueue).

Как правило, это хорошая практика, поскольку они позаботятся о синхронизации за вас.Я предполагаю, что есть лучший способ решить вашу проблему.Какую реальную проблему вы пытаетесь решить?

Вторая ошибка вызвана тем фактом, что вы ДОЛЖНЫ владеть блокировкой/монитором объекта (путем синхронизации на нем), чтобы вызывать на нем wait/notify/notifyAll.

BlockingQueue — это синхронизатор объект — координирует поток управления потоками на основе его состояния и, таким образом, управляет потоком потоков производителя/потребителя, потому что брать и помещать блокировать до тех пор, пока очередь не перейдет в нужное состояние (не пустое и не заполненное).

Также хорошая практика параллельного программирования предполагает, что ожидание и уведомление помещаются в цикл while.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top