简体   繁体   中英

scjp: threads related issue

below is the question...

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

Which statement is true?

A. This code can throw an InterruptedException .

B. This code can throw an IllegalMonitorStateException .

C. This code can throw a TimeoutException after ten minutes.

D. Reversing the order of obj.wait() and obj.notify() might cause this method to complete normally.

E. A call to notify() or notifyAll() from another thread might cause this method to complete normally.

F. This code does NOT compile unless obj.wait() is replaced with ((Thread) obj).wait() .

Answer is B . But when i have executed in below manner getting A. Please help.

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();
    }    
}   

And also tried below :

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();
    }    
}  

This code doesn't compile. Answer A means the code would throw InterruptedException while running. Your code has a compile error where obj.wait can throw InterruptedException and the exception isn't handled and the method is not declared as throwing it, so the class can't compile. So Answer A is not applicable here.

Of course the code from the question has the same problem. So the question seems flawed.

Once you fix the compile error, and move the waitForSignal call into the Thread's run method so that it gets called by the sd thread instead of the main thread, you should have something like:

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();
    }    
} 

then you should get the expected result:

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)

This will compile only if its surrounded with try and catch now coming on the explanation

-If the thread calling wait() does not own the lock on the object, a IllegalMonitorStateException will be thrown.

-Here we haven't take lock for obj we are taking lock for current thread object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM