简体   繁体   中英

Entering in block with an Intrinsic Lock

I don't see how the following code produces output that appears to contravene the definition of an object lock. Surely only one thread should be allowed to print the "acquired lock" message yet they both do?

class InterruptThreadGroup {
    public static void main(String[] args) {
        Object lock = new Object();
        MyThread mt1 = new MyThread(lock);
        MyThread mt2 = new MyThread(lock);
        mt1.setName("A");
        mt1.start();
        mt2.setName("B");
        mt2.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        // Thread.currentThread().getThreadGroup().interrupt();
    }
}

class MyThread extends Thread {
    private Object lock;

    public MyThread(Object l) {
        this.lock = l;

    }

    public void run() {
        synchronized (lock) {
            System.out.println(getName() + " acquired lock");
            try {
                lock.wait();
            } catch (InterruptedException e) {
                System.out.println(getName() + " interrupted.");
            }
            System.out.println(getName() + " terminating.");
        }
    }
}

It is because the call to lock.wait() releases the lock, allowing the second thread to enter the synchronized block. Extract from the javadoc

The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

Note that there are a few issues in your code such as:

  • you should not wait outside of a while loop
  • there is no notify anywhere so your wait could last forever
  • it is a better practice to have your task implement Runnable and pass it as an argument to a Thread's constructor than to extend Thread directly.

Either you should use synchronized block or wait call . using them together will not work. if you use wait call then the lock is released by the object in synchronized block.

So remove the line lock.wait and your programme will work as you want. synchronize block will handle all lock automatically.

if you are using wait then must use notify.

Here is good thread about this: Why must wait() always be in synchronized block

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