为什么同步方法允许多个线程同时运行?

use*_*089 8 java multithreading synchronized

我在同一个文件中有以下程序.我已经同步了run()方法.

class MyThread2 implements Runnable {
    Thread    t;

    MyThread2(String s) {
        t=new Thread(this,s);
        t.start();
    } 

    public synchronized  void  run() {
        for (int i=0;i<3;i++) {
            System.out.println("Thread name : "+ Thread.currentThread).getName());
            try {
                t.sleep(1000);
            }
            catch (InterruptedException e) {
                e.getMessage();
            }
        }
    }
}

class TestSync {
    public static void main(String[] args) {
        MyThread2 m1=new MyThread2("My Thread 1");
        c.fun();
    }
}

class c {
    static void fun() {
        MyThread2 m1=new MyThread2("My Thread 4");
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是

Thread name : My Thread 1
Thread name : My Thread 4
Thread name : My Thread 4
Thread name : My Thread 1
Thread name : My Thread 1
Thread name : My Thread 4
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么同步方法同时允许"我的线程1"和"我的线程4"线程访问?

NPE*_*NPE 30

synchronized方法在实例级别工作.该类的每个实例都有自己的锁.每次synchronized输入实例的任何方法时都会获取锁.这可以防止多个线程在同一个实例上调用synchronized方法(请注意,这也可以防止在同一个实例上调用不同的方法). synchronized

现在,由于您有两个类的实例,每个实例都有自己的锁.没有什么可以防止两个线程同时在它自己的实例上运行.

如果你想要阻止这种情况,你可以在synchronized(obj)里面有一个块run(),在这里obj你的类的两个实例共享一些对象:

class MyThread2 implements Runnable {
   private static final Object lock = new Object();
   ...
   public void run() {
     synchronized(lock) {
       ...
     }
   }
}
Run Code Online (Sandbox Code Playgroud)