Java线程同步 - Thread.sleep()方法不按预期工作

jas*_*ssu 4 java multithreading synchronization sync

我听说,sleep()将锁定当前的sync方法/块但是在这里,当我在线程1上调用sleep()时,线程2能够访问同一个块吗?谁能解释一下吗?

Main.java

public class Main {     
    public static void main(String args[])
    {
        Thread1 t1 = new Thread1();
        Thread2 t2 = new Thread2();
        System.out.println("going to start t1");
        t1.start();
        System.out.println("going to start t2");
        t2.start();

    }

}
Run Code Online (Sandbox Code Playgroud)

================================================== ===================

Thread1.java

public class Thread1 extends Thread{

    public void run() { 
        Syncc s1 = new Syncc();
        s1.me("T1:");
    }   

}
Run Code Online (Sandbox Code Playgroud)

================================================== ===================

Thread2.java

public class Thread2 extends Thread{

    public void run() { 
        Syncc s2 = new Syncc();
        s2.me("T2:");
    }   
}
Run Code Online (Sandbox Code Playgroud)

================================================== ===================

Syncc.java

public class Syncc{

    public void me(String s){
        synchronized(this){
        for(int i=0; i<=5; i++)
        {
            System.out.println(s+" "+" "+i);
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {              
                e.printStackTrace();
            }
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

==========================================

输出:

going to start t1
going to start t2
T2:  0
T1:  0
T2:  1
T1:  1
T1:  2
T2:  2
T1:  3
T2:  3
T1:  4
T2:  4
T2:  5
T1:  5
Run Code Online (Sandbox Code Playgroud)

但是根据sleep()方法,它不应该解锁当前的同步块吗?如果是这样,输出应该是......

将开始t1开始t2

T1:  0
T1:  1
T1:  2
T1:  3
T1:  4
T1:  5
T2:  0
T2:  1
T2:  2
T2:  3
T2:  4
T2:  5
Run Code Online (Sandbox Code Playgroud)

我的意思是在线程1执行后,只有线程2应该正确启动?问题是什么?

ada*_*shr 9

这是因为你Syncc在这里有两个不同的实例.每个线程都有自己的副本Syncc.

尝试对单个实例执行相同操作.您还可以在静态上下文中进行同步并尝试.

模拟,修改Thread1Thread2接受实例Syncc.

public class Thread1 extends Thread {
    private Syncc syncc;

    public Thread1(Syncc syncc) {
        this.syncc = syncc;
    }

    public void run() { 
        this.syncc.me("T1:");
    }   
}
Run Code Online (Sandbox Code Playgroud)

然后您可以这样启动它们:

public static void main(String args[]) {
    Syncc syncc = new Syncc();

    Thread1 t1 = new Thread1(syncc);
    Thread2 t2 = new Thread2(syncc);

    System.out.println("going to start t1");
    t1.start();
    System.out.println("going to start t2");
    t2.start();
}
Run Code Online (Sandbox Code Playgroud)