IllegalMonitorStateException - CyclicBarrier - PullRequest
       6

IllegalMonitorStateException - CyclicBarrier

2 голосов
/ 03 декабря 2010

У меня есть метод, который использует CyclicBarrier, как показано ниже:

public void getMessage(Message obj){
    CyclicBarrier barrier = new CyclicBarrier(1, new Runnable() {
        @Override
        public void run() {
            synchronized(obj){ 
                System.out.println("--The End --");
            }
        }
    });

    executor.execute(new Runnable() {
        @Override
        public void run() {
            synchronized(obj){
                //Perform some routine with message object
            }
            try {
                barrier.wait();//java.lang.IllegalMonitorStateException thrown on this line
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });
}

В тот момент, когда я жду, пока подпрограмма завершит выполнение, я получаю:

Exception in thread "pool-2-thread-3"
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)

Кто-нибудь знает, что я здесь не так делаю?

Ответы [ 5 ]

5 голосов
/ 03 декабря 2010

Чтобы вызвать wait() для любого объекта, текущий поток должен иметь свой монитор.Вы звоните barrier.wait() без каких-либо synchronized(barrier).

Однако вы, возможно, хотели использовать метод await() (в CyclicBarrier) вместо wait().Трудно сказать, поскольку неясно, чего вы пытаетесь достичь.

0 голосов
/ 03 декабря 2010

Циклический барьер не предназначен для использования, как вы делаете здесь: ожидается, что участвующие потоки вызовут блокирующий метод "await ()".

В качестве примечания, CyclicBarrier со счетчиком 1 равенсовершенно бесполезно: его цель - позволить определенному количеству потоков (количество барьеров) ждать друг друга, прежде чем продолжить.Может быть, вам стоит подумать об изменении всего алгоритма, особенно если вы не уверены, как работает параллелизм.

0 голосов
/ 03 декабря 2010

Вам необходимо получить замок перед использованием объекта барьера.

С уважением, Дхирадж Джоши

0 голосов
/ 03 декабря 2010

Может быть, вы хотите использовать await() вместо этого wait()?

wait, чтобы блокировать поток над определенным объектом, и это особенность каждого объекта, но в вашем случаеВы называете это, не беря монитор этого.Вы должны вызывать wait из того же объекта или использовать блок synchronized над barrier.

0 голосов
/ 03 декабря 2010

да, вам нужно получить монитор барьера следующим образом:

synchhronized(barrier){
try {
     barrier.wait();//java.lang.IllegalMonitorStateException not thrown on this line
    } catch (InterruptedException e) {
    e.printStackTrace();
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...