2015-10-19 4 views
1

Привет Я работаю над дампами SCJP, но теперь у меня возникла проблема. Возникает вопрос:OCJP Dumps Thread Synchronized Method

void waitForSignal(){ 
    Object obj = new Object(); 
    synchronized(Thread.currentThread()){ 
     obj.wait(); 
     obj.notify(); 
    } 
} 

Какое утверждение верно?

А. Этот код может бросить InterruptedException

Б. Этот код может бросить illegalMonitorStateException

C. Этот код может бросить TimeoutException после десяти минут

Д. Реверсивный порядок OBJ .wait() и obj.notify() могут привести к тому, что этот метод будет нормально завершен

E. Вызов уведомления() или notifyAll() из другого потока может привести к тому, что этот метод будет нормально завершен

F. Этот код не компилируется, если "obj.wait()" не заменить "((Thread) OBJ) .wait()"

я обнаружил, что в одном из файла дампа ответ A, в то время как в другой дампе ответ: B. Может ли кто-нибудь получить правильный ответ и дать объяснение мне?

ответ

0

Определенно B здесь является правильным. Обратитесь к документации по API для IllegalMonitorStateException:

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

Монитор, приобретенный, представляет собой текущую нить (которую, кстати, предостерегает от документации API). Методы wait and notify вызывают на obj, где они должны были быть вызваны на текущий объект потока.

A. Объект # wait может вызывать InterruptedException. Если это происходит, зависит от реализации, то language spec говорит:

Пусть нить Т поток, выполняющий метод ожидания на объекте м, и пусть п число шлюзовых действий т на т, которые не соответствовали путем разблокировки действий. Один из следующих действий происходят:

  • Если п равно нуль (то есть, поток т ли уже не обладает замком для целевых м), то IllegalMonitorStateException выбрасывается.

  • Если это время ожидания и аргумент nanosecs не находится в диапазоне 0-999999, или аргумент миллисекунда отрицательный, то генерируется исключение IllegalArgumentException.

  • Если поток t прерван, то генерируется прерывание Exception и состояние прерывания t установлено в false.

  • В противном случае, следующая последовательность событий: (...)

так что это не строго определено, какой из этих случаев будет проверяться первым.На практике InterruptedException не попадает в Oracle или IBM JDK, что делает IllegalMonitorStateException.

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

public class Test implements Runnable { 

    public void run() { 
     Object obj = new Object(); 
     Thread.currentThread().interrupt(); 
     try { 
      synchronized(Thread.currentThread()) { 
       obj.wait(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     new Thread(new Test()).start(); 
    } 
} 

Так что, может быть, теоретически это правильно. Вопросы, связанные с сертификационными испытаниями, должны быть достаточно четкими, что спецификация немного двусмысленна в этом вопросе, заставляет меня думать, что это не большой тестовый вопрос.

C. «Исключение времени ожидания» является фиктивным. Если время ожидания с истечением времени ожидания истекает, метод возвращается нормально.

D. Реверсирование порядка ожиданий и уведомлений не имеет значения, они оба имеют одинаковое требование.

E. Ничего не сделанное другим потоком может сделать эту нить законченной, как она написана.

F. Метод wait находится на объекте, а не в потоке, не требуется литье.

Учитывая, что B определенно верно, и он описывает важный момент, который должен быть понят Java-программистами, в то время как A основан на неясном придирчивости о спецификации, если вы можете выбрать только один ответ, который я бы рекомендовал B.