Java 线程中的静态同步和非静态同步方法

Java 线程中的静态同步和非静态同步方法,java,multithreading,Java,Multithreading,任何人都可以解释这句话吗?“静态同步方法和非静态同步方法不会相互阻塞-它们可以同时运行”静态方法和非静态方法上的锁对象不同。静态方法使用类对象作为锁(lock obj:MyClass.Class),而非静态方法使用实例对象作为锁,此时方法的调用将绑定到该锁(lock obj:this) 相等于 static void test() { synchronized(MyClass.class) { foo(); } } 当 synchronized void test() { foo(); }

任何人都可以解释这句话吗?“静态同步方法和非静态同步方法不会相互阻塞-它们可以同时运行”

静态方法和非静态方法上的锁对象不同。静态方法使用类对象作为锁(lock obj:
MyClass.Class
),而非静态方法使用实例对象作为锁,此时方法的调用将绑定到该锁(lock obj:
this

相等于

static void test() { synchronized(MyClass.class) { foo(); } }

synchronized void test() { foo(); }
相等于

void test() { synchronized(this) { foo(); } }

这意味着:静态方法锁定类的类对象。非静态方法锁定调用它们的实例(默认情况下,
synchronized(anyOtherLock)
)。由于它们锁定在不同的对象上,因此它们不会相互阻止。

非静态同步方法将监视器锁定在“this”上-这意味着只有当前对象被锁定。因此,如果任何一个线程正在访问非静态同步方法,则与当前对象关联的所有线程都将被阻止访问该类的非静态同步方法。而其他对象的线程仍然可以访问这些方法

静态同步方法将监视器锁定在类对象上——这意味着,如果任何对象的线程正在访问该方法,那么所有线程(无论任何对象)都将被阻止访问该类的所有静态同步方法

公共类测试同步{

public synchronized void n1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync non static n1 " + threadId);
}

public void n2(int threadId)
{ 
    snooze(threadId);
    System.out.println(" non static n2 " + threadId);
}

public static synchronized void s1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync static s1 "+  threadId);
}

public static void s2(int threadId)
{
    snooze(threadId);
    System.out.println(" static s2 "+  threadId);
}

static void snooze(int threadId)
{
    System.out.println("Waiting ... "+ threadId);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    TestSync ob = new TestSync();
    TestSync ob2=new TestSync();
    TestSync ob3=new TestSync();
    TestSync ob4=new TestSync();

    Runnable r1=()-> {
        /*ob.n1(10);
        ob.n2(10);*/
        ob.s1(10);
        //ob.s2(10);
    };

    Runnable r3=()-> {
        /*ob2.n1(30);
        ob2.n2(30);*/
        ob2.s1(30);
        //ob2.s2(30);
    };

    Runnable r4=()-> {
        /*ob3.n1(40);
        ob3.n2(40);*/
        ob3.s1(30);
        //ob3.s2(30);
    };

    Thread t1=new Thread(r1);
    Thread t2= new Thread(r2);
    Thread t3= new Thread(r3);
    Thread t4= new Thread(r4);
    Thread t5= new Thread(r5);
    t1.start();
    t3.start();
    t4.start();

}
}
为静态同步运行一次,然后在runnable和Run中取消对非静态同步调用(和注释static synchronized)的注释。你会更好地理解。

可能重复你说的内容,但你能解释更多与那句话有关的内容吗。这样我就清楚了,它们可以同时在不同的线程中运行,因为锁对象是不同的。线程安全通常是通过在不同的线程中使用相同的锁对象来确保的,以使这些线程之间的代码执行在任何时间点都是互斥的?让我困惑。锁定对象:这个。是的,你对这个的锁定,不是一个新对象。对不起,改变了。只是试图显示一个实例,但“this”要好得多:)
public synchronized void n1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync non static n1 " + threadId);
}

public void n2(int threadId)
{ 
    snooze(threadId);
    System.out.println(" non static n2 " + threadId);
}

public static synchronized void s1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync static s1 "+  threadId);
}

public static void s2(int threadId)
{
    snooze(threadId);
    System.out.println(" static s2 "+  threadId);
}

static void snooze(int threadId)
{
    System.out.println("Waiting ... "+ threadId);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    TestSync ob = new TestSync();
    TestSync ob2=new TestSync();
    TestSync ob3=new TestSync();
    TestSync ob4=new TestSync();

    Runnable r1=()-> {
        /*ob.n1(10);
        ob.n2(10);*/
        ob.s1(10);
        //ob.s2(10);
    };

    Runnable r3=()-> {
        /*ob2.n1(30);
        ob2.n2(30);*/
        ob2.s1(30);
        //ob2.s2(30);
    };

    Runnable r4=()-> {
        /*ob3.n1(40);
        ob3.n2(40);*/
        ob3.s1(30);
        //ob3.s2(30);
    };

    Thread t1=new Thread(r1);
    Thread t2= new Thread(r2);
    Thread t3= new Thread(r3);
    Thread t4= new Thread(r4);
    Thread t5= new Thread(r5);
    t1.start();
    t3.start();
    t4.start();

}