scjp: проблема, связанная с потоками

ниже вопрос...

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

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

О. Этот код может вызвать ошибку InterruptedException.

B. Этот код может вызвать ошибку IllegalMonitorStateException.

C. Этот код может выдать TimeoutException через десять минут.

D. Изменение порядка obj.wait() и obj.notify() может привести к нормальному завершению этого метода.

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

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

Ответ Б. Но когда я выполнил описанным ниже образом, получил A. Пожалуйста, помогите.

public class ThreadStateProblem extends Thread {  
    public void run() {  

    }  

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

    public static void main(String []s) {  
        new ThreadStateProblem().start();  
        new ThreadStateProblem().waitForSignal();
    }    
}   

А также попробовал ниже:

public class ThreadStateProblem extends Thread {  
    public void run() {  

    }  

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

    public static void main(String []s) {  
        ThreadStateProblem sd =new ThreadStateProblem();
        sd.start();
        sd.waitForSignal();
    }    
}  

person user3066920    schedule 20.02.2014    source источник
comment
Почему вы создаете два объекта ThreadStateProblem? Потому что вы вызываете start() в одном потоке и waitForSignal() в другом.   -  person Darth Hunterix    schedule 20.02.2014
comment
только что попробовал ....... без конкретной причины ....... также пробовал с тем же объектом ...... получаю то же самое.... открытый класс ThreadStateProblem extends Thread { public void run() { } void waitForSignal() { Объект obj = новый объект(); синхронизировано (Thread.currentThread()) { obj.wait(); объект.уведомить(); } } public static void main(String []s) { ThreadStateProblem sd =new ThreadStateProblem(); сд.старт(); sd.waitForSignal(); } }   -  person user3066920    schedule 20.02.2014
comment
Я думаю, вы хотите поместить этот код в вопрос, здесь, в разделе комментариев, он нечитаем.   -  person Darth Hunterix    schedule 20.02.2014
comment
и что произойдет, если вы вызовете waitForSignal() в методе run()?   -  person Darth Hunterix    schedule 20.02.2014


Ответы (2)


Этот код не компилируется. Ответ A означает, что код выдаст InterruptedException во время работы. В вашем коде есть ошибка компиляции, когда obj.wait может генерировать InterruptedException, и исключение не обрабатывается, а метод не объявлен как его генерирующий, поэтому класс не может скомпилироваться. Так что ответ А здесь неприменим.

Конечно, код из вопроса имеет ту же проблему. Так что вопрос кажется некорректным.

Как только вы исправите ошибку компиляции и переместите вызов waitForSignal в метод run потока, чтобы он вызывался потоком sd вместо основного потока, у вас должно получиться что-то вроде:

public class ThreadStateProblem extends Thread {  
    public void run() {  
        waitForSignal();
    }  

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

    public static void main(String []s) {  
        ThreadStateProblem sd =new ThreadStateProblem();
        sd.start();
    }    
} 

то вы должны получить ожидаемый результат:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:503)
    at ThreadStateProblem.waitForSignal(ThreadStateProblem.java:10)
    at ThreadStateProblem.run(ThreadStateProblem.java:3)
person Nathan Hughes    schedule 20.02.2014

Это будет скомпилировано, только если оно окружено try and catch, теперь идет объяснение

-Если поток, вызывающий wait(), не владеет блокировкой объекта, будет выброшен IllegalMonitorStateException.

-Здесь мы не берем блокировку для объекта, мы берем блокировку для текущего объекта thread.

person Bhargav Modi    schedule 22.03.2015