简体   繁体   English

使用内在锁进入块

[英]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. 这是因为对lock.wait()的调用释放了锁,允许第二个线程进入synchronized块。 Extract from the javadoc 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. 线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。 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 你不应该在while循环之外等待
  • 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. 让你的任务实现Runnable并将其作为参数传递给Thread的构造函数而不是直接扩展Thread是一种更好的做法。

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. 所以删除行lock.wait ,你的程序将按你的意愿工作。 synchronize block will handle all lock automatically. synchronize block将自动处理所有锁定。

if you are using wait then must use notify. 如果您正在使用等待,那么必须使用通知。

Here is good thread about this: Why must wait() always be in synchronized block 这是关于这个的好主题: 为什么wait()总是在同步块中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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