Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步块don';使用不相关类的成员作为锁对象时不起作用?_Java_Multithreading_Synchronization - Fatal编程技术网

Java 同步块don';使用不相关类的成员作为锁对象时不起作用?

Java 同步块don';使用不相关类的成员作为锁对象时不起作用?,java,multithreading,synchronization,Java,Multithreading,Synchronization,我在同步块上找到的几乎所有资源都使用这个或类的一个成员作为锁对象。我感兴趣的是找出当lock对象是另一个类的(静态)成员时,为什么不能让同步块工作。下面是我的代码来说明这个问题: public class Test { public static void main(String[] args) { Thread thread1 = new FirstThread(); Thread thread2 = new SecondThread();

我在同步块上找到的几乎所有资源都使用这个或类的一个成员作为锁对象。我感兴趣的是找出当lock对象是另一个类的(静态)成员时,为什么不能让同步块工作。下面是我的代码来说明这个问题:

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
显然,第二个线程在第一个线程离开其块之前进入同步块。有人能解释一下我遗漏了什么吗? 我认为同步块的目的就是为了防止这种情况。是因为锁对象是另一个类的成员吗?

引用自:

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

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

引用自:

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


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

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

请注意,sleep()不是


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

请注意,sleep()不是


当您调用lock时。您可以“释放此监视器的所有权”。这允许线程2在调用lock时进入synchronized块。

。您可以“释放此监视器的所有权”。这允许线程2进入同步块。

是的,我在谷歌搜索了一个不相关的问题后意识到了这一点。我的脸现在很红。是的,我在谷歌搜索了一个不相关的问题后意识到了这一点。我的脸现在很红。