Java 两个线程在实例级锁上同时进入两个不同的synchrnozied方法

Java 两个线程在实例级锁上同时进入两个不同的synchrnozied方法,java,multithreading,Java,Multithreading,我在一次采访中被问到,关于多线程,假设在同一个对象上有两个线程(线程1和线程2)。线程1在synchronized method1()中,线程2可以通过任何方式在java中同时进入synchronized method2() 我回答“否”,这里,当线程1处于synchronized method1()中时,它必须在对象的监视器上保持锁定,并且只有在退出synchronized method1()时才会释放对象监视器上的锁定。所以,线程2必须等待线程1释放对象监视器上的锁,以便它可以进入synch

我在一次采访中被问到,关于多线程,假设在同一个对象上有两个线程(线程1和线程2)。线程1在synchronized method1()中,线程2可以通过任何方式在java中同时进入synchronized method2()

我回答“否”,这里,当线程1处于synchronized method1()中时,它必须在对象的监视器上保持锁定,并且只有在退出synchronized method1()时才会释放对象监视器上的锁定。所以,线程2必须等待线程1释放对象监视器上的锁,以便它可以进入synchronized method2()

但是仍然请告知Thread-2是否有任何方法可以在java中同时输入synchronized method2(),是否有任何方法可以实现这一点

下面是我的程序,rite现在我已经更改了实现,请对此提出建议,因为下面程序的输出是

inside M1()
t1--->RUNNABLE
inside M2()
t2--->RUNNABLE
下面是我的更新代码

public class Test {

     private final Object lockA = new Object();
     private final Object lockB = new Object();

    public  void m1() {
         synchronized(lockA) {
        try {
            System.out.println("inside M1()");
            Thread.sleep(100);         
        }
        catch (InterruptedException ie) 
        {}
         }
    }

    public  void m2() {
        synchronized(lockB) {
        try { 
            System.out.println("inside M2()");
            Thread.sleep(100); }
        catch (InterruptedException ie) {}
    }
    }

    public static void main(String[] args) throws InterruptedException {
        final Test t = new Test();
        Thread t1 = new Thread()
        { public void run() { t.m1(); } };
        Thread t2 = new Thread()
        { public void run() { t.m2(); } };

        t1.start();
        //Thread.sleep(500);

        t2.start();
      //  Thread.sleep(500);

        System.out.println("t1--->"+t1.getState());
        System.out.println("t2--->"+t2.getState());
    }
}

请注意,在您的示例中,即使MyRunnable1类有一个method1(),并且您的run()函数在循环中调用此方法,线程也不会在任何事情上竞争。因为thread1和thread2是不同的实例,并且每个实例都有自己的method1()副本,所以synchronized使用的锁是不同的,而不是一个锁。

两个线程不能同时持有同一个锁。但是,仅仅因为线程位于对象的
同步
方法中,并不意味着它持有锁。例如,它可以对条件变量调用
await
,并在等待时释放锁。这允许其他线程通过输入
synchronized
方法获得锁——毕竟,这就是您所等待的

void method1(){
      synchronized(this) {
           //...
      }
}

synchronized void method2(){
      synchronized(this) {
           //...
      }
}

在代码中,两个线程不能同时为锁争用输入两个方法。您只能在runnable的不同实例上执行此操作,即不同的实例。

您已正确理解,每个对象都有与其关联的锁,并且一旦Thread1获取了访问同步方法1的锁,Thread2就无法访问同步方法2

现在,来看看特例,你们可以做一个简单的破解。假设Thread1拥有锁,并且正在访问synchronized method1。在method1内部,如果Thread1调用变量wait,那么它会释放对象上的锁并进入wait状态。在此场景中,Thread2可以获取锁并进入synchronized method2。因此,两个线程都可以访问同一obj上的不同同步方法


p.S.这只是一个例子,我不建议在同步块内进行另一次等待,这将导致不必要的复杂性。如果有任何代码必须这样做,那么这意味着逻辑和设计中存在缺陷。

重复,但仍然没有证据表明两个线程同时获得了相同的锁。您的建议基本上是不可想象的。@EJP,Thnaks,但请告知您如何简单地证明获得了哪个锁,是否有任何方法可以查看锁名advise@Ejp请检查这个解决方案太我不同意你,因为他使用单一runnable,使用相同的锁。方法也是共享的,没有其他副本。你是对的,我没有注意到对不起,我错了这个帖子中唯一正确的答案,唯一一个投了反对票的答案…这是不正确的。看看我的答案——其中一个
/…
可能包含释放锁并让另一个线程进入
同步的
块的代码。@DavidSchwartz我在他的旧代码示例中说,他不能这样做,除非使用不同的实例。:)