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()
,
Ответ Б. Но когда я выполнил приведенный ниже способ, получая А. Пожалуйста, помогите.
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();
}
}
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)
Это скомпилируется, только если он окружен try and catch
сейчас идет объяснение
-Если поток вызывает wait()
не владеет замком на объекте, IllegalMonitorStateException
будет брошен.
-Здесь мы не взяли блокировку для объекта, мы взяли блокировку для текущего thread
объект.