代码之家  ›  专栏  ›  技术社区  ›  Isabel Jinson

两个同步方法是否同时执行

  •  31
  • Isabel Jinson  · 技术社区  · 15 年前

    我有四种方法( m1 , m2 , m3 m4 m1级 平方米 synchronized t1 , t2 t3 t4 分别。

    t1级 访问 t2级 同步方法?如果不是,t2的状态会是什么?

    4 回复  |  直到 9 年前
        1
  •  47
  •   aioobe    9 年前

    如果t1访问m1方法(synchronized method),那么t2线程可以同时访问m2方法(synchronized method)吗?

    这个 synchronized 对象级别 ,并且只有一个线程可以持有对象的锁。所以只要你说的是同一个物体 , t2 t1 释放进入时获得的锁 m1 .

    Object.wait()

    如果不是,t2的状态是什么?

    它会坐以待毙 t1级 释放锁(从方法或调用返回) ). 具体来说,它将在一个 BLOCKED state .

    Object.wait .

    public class Test {
    
        public synchronized void m1() {
            try { Thread.sleep(2000); }
            catch (InterruptedException ie) {}
        }
    
        public synchronized void m2() {
            try { Thread.sleep(2000); }
            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(t2.getState());
        }
    }
    

    输出:

    BLOCKED
    
        2
  •  11
  •   Andrzej Doyle    15 年前

    如果这些方法在同一个监视器上同步,那么它们就不能在不同的线程中同时执行。当第二个线程到达监视器条目(本例中是synchronized方法的开始)时,它将阻塞,直到第一个线程释放监视器。

    在本例中,jconsole报告的阻塞线程的实际状态如下 java.lang.Thread.State: WAITING (on object monitor)

    假设所有方法都是普通实例方法,那么它们将共享同一个监视器 . 也就是说,如果你有这样的东西:

    // Thread 1
    A a1 = new A();
    a1.m1();
    
    // Thread 2
    A a2 = new A();
    a2.m2()
    

    在本例中,第二个线程将能够调用该方法,因为它试图获取 a2 对象,即 被线程1锁定。但是如果线程2试图调用 a1.m2() ,然后它将阻塞,直到线程1完成执行 m1() .

    如果您有静态方法,那么它们将获得类本身的显式监视器( A.class 任何

        3
  •  4
  •   Kilian Foth    15 年前

    不,不可能。这是唯一的一点 synchronized :不同的线程不能同时执行这些操作(您不必防止同一个线程同时执行这些操作,因为单个线程根本不能并行执行任何操作。)等待线程的状态是“等待锁定”(使用一个足够现代的JVM,如果您以正确的方式询问,您实际上可以在控制台上显示这个状态。)

        4
  •  1
  •   Community CDub    5 年前

    在同一个示例中,t2可以访问不同步的方法m4。

    锁定 synchronized 方法

    当线程调用同步方法时,它会自动获取该方法对象的内在锁,并在方法返回时释放它。即使返回是由未捕获的异常引起的,也会发生锁释放

    回到第二个问题:

    线程t2处于阻塞状态,正在等待线程t1释放锁。

    来自java documentation

    制作 synchronized

    首先,不可能对同一对象上的两个同步方法调用进行交错。当一个线程为一个对象执行同步方法时,为同一个对象调用同步方法的所有其他线程都会阻塞(暂停执行),直到第一个线程处理完该对象为止。

    其次,当同步方法退出时,它会自动与同一对象的同步方法的任何后续调用建立“发生在”关系。这保证了对对象状态的更改对所有线程都是可见的