繁体   English   中英

将不相关类的成员用作锁定对象时,同步块不起作用?

[英]Synchronized blocks don't work when using member of unrelated class as lock object?

我在同步块上发现的几乎所有资源都使用此资源或该类的成员作为锁定对象。 我有兴趣找出为什么当锁定对象是另一个类的(静态)成员时,为什么无法使同步块工作。 这是我的代码来说明问题:

public class Test {
        public static void main(String[] args) {
        Thread thread1 = new FirstThread();
        Thread thread2 = new SecondThread();
        thread1.start();
        thread2.start();
        }
    }

class FirstThread extends Thread {
    @Override
    public void run() {
        synchronized (Lock.lock) {
            System.out.println("First thread entered block");
            try {
                Lock.lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("First thread exited block");
    }
}

class SecondThread extends Thread {
    @Override
    public void run() {
        try {
            Thread.sleep(1000); //just making sure second thread enters synch block after first thread
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (Lock.lock) {
            System.out.println("Second thread entered block");
            Lock.lock.notifyAll();
        }
        System.out.println("Second thread exited block");
    }
}

class Lock {
    public static Object lock = new Object();
}

我的理解是,在第一个线程退出之前,第二个线程应该不能进入同步块,因为它们在同一对象上同步。 因此,我期望程序在“第一个线程进入块”之后挂起(死锁?),因为第二个线程无法进入该块,第一个线程将被卡住以等待通知。 但是相反,我得到了以下输出:

First thread entered block

Second thread entered block

Second thread exited block

First thread exited block

显然,第二个线程在第一个线程离开其块之前就进入了同步块。 有人可以解释我所缺少的吗? 我认为同步块的目的是为了防止这种情况。 是否因为锁对象是另一个类的成员?

第一个线程Lock.lock.wait()放弃对同步对象的锁定,以便其他线程可以输入关键路径并唤醒等待者。

请注意,sleep()相反。

wait()和sleep()之间的区别

引用Object.wait()javadoc

线程释放此监视器的所有权,并等待直到另一个线程通过调用notify方法或notifyAll方法通知等待在此对象监视器上等待的线程唤醒。

如果不是这种情况,则等待将系统地导致死锁,因为没有线程能够进入调用notify()notifyAll()所需的同步部分,从而使等待和通知完全无用。

当您调用锁时。 等待您“释放此监视器的所有权”。 这允许线程2进入同步块。

暂无
暂无

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

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