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

Java线程同步-Thread.sleep()方法未按预期工作,java,multithreading,synchronization,sync,Java,Multithreading,Synchronization,Sync,我听说,sleep()将锁定当前的同步方法/块 但是在这里,当我在线程1上调用sleep()时,线程2能够访问相同的块吗?有人能解释一下吗 主类 ===================================================================== Thread1.java ===================================================================== Thread2.java ===========

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

主类 =====================================================================

Thread1.java =====================================================================

Thread2.java =====================================================================

Syncc.java 但是根据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
我的意思是在线程1执行之后,只有线程2应该正确启动?
什么问题

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

public class Thread1 extends Thread {
    private Syncc syncc;

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

    public void run() { 
        this.syncc.me("T1:");
    }   
}
尝试对单个实例执行相同的操作。您还可以在静态上下文上进行同步,然后重试

要进行模拟,请修改
Thread1
Thread2
以接受
Syncc
的实例

public class Thread1 extends Thread {
    private Syncc syncc;

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

    public void run() { 
        this.syncc.me("T1:");
    }   
}
然后,您可以按如下方式启动它们:

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();
}

睡眠、屈服和加入的规则

  • 睡眠用于将执行延迟一段时间,并且不使用锁 当线程进入睡眠状态时释放

  • 保证休眠线程至少在中指定的时间内休眠 sleep()方法的参数(除非它被中断),但是 无法保证新唤醒的线程何时实际返回 正在运行。

  • sleep()方法是一个静态方法,用于睡眠当前正在执行的 线程的状态。一个线程不能告诉另一个线程睡眠

  • setPriority()方法用于线程对象以提供线程 优先级介于1(低)和10(高)之间,尽管优先级不是 保证,但并非所有JVM都能识别10个不同的优先级 水平可被视为有效相等

  • 如果未显式设置,线程的优先级将与 创建它的线程的优先级

  • 如果存在,yield()方法可能会导致正在运行的线程退出 具有相同优先级的可运行线程。不能保证这会发生 当线程返回时,无法保证 将选择一个不同的线程来运行。一根线可能会屈服,然后 立即重新进入运行状态

  • 最接近于保证的是,在任何给定的时间,当线程 在运行时,它的优先级通常不会低于 可运行状态。如果低优先级线程正在运行,而高优先级线程正在运行 进入runnable,JVM通常会抢占正在运行的低优先级 线程并将高优先级线程放入

  • 当一个线程调用另一个线程的join()方法时,当前 正在运行的线程将等待它所连接的线程完成。思考 对join()方法的解释是:“嘿,线程,我想连接到底 谢谢你。完成后请告诉我,这样我就可以进入可运行状态。”


您已经创建了两个同步对象,每个对象对应一个线程。每个对象都有自己的“我”副本。因此,当您启动每个线程时,使用run方法,线程正在调用自己的函数me副本。由于两个线程只作用于它们的副本,因此这类似于单线程场景。如果您确实想测试多线程场景,那么将方法me设置为静态(类级方法),并应用类级锁

Thread1.java

public class Thread1 extends Thread{

public void run() { 
    Syncc.me("T1:");
}   
public class Thread2 extends Thread{

public void run() { 
    Syncc.me("T2:");
}   
public class Syncc{

public static void me(String s){
    synchronized(Syncc.class){
    for(int i=0; i<=5; i++)
    {
        System.out.println(s+" "+" "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {              
            e.printStackTrace();
        }
    }
}
}

Thread2.java

public class Thread1 extends Thread{

public void run() { 
    Syncc.me("T1:");
}   
public class Thread2 extends Thread{

public void run() { 
    Syncc.me("T2:");
}   
public class Syncc{

public static void me(String s){
    synchronized(Syncc.class){
    for(int i=0; i<=5; i++)
    {
        System.out.println(s+" "+" "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {              
            e.printStackTrace();
        }
    }
}
}

Syncc.java

public class Thread1 extends Thread{

public void run() { 
    Syncc.me("T1:");
}   
public class Thread2 extends Thread{

public void run() { 
    Syncc.me("T2:");
}   
public class Syncc{

public static void me(String s){
    synchronized(Syncc.class){
    for(int i=0; i<=5; i++)
    {
        System.out.println(s+" "+" "+i);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {              
            e.printStackTrace();
        }
    }
}
公共类同步{
公共静态void me(字符串s){
已同步(Syncc.class){

对于(int i=0;iThread1和Thread2使用不同的Syncc实例,因此它们访问两个不同Syncc实例的方法me(),所以同步块不起作用。明白了,非常感谢lotz adarshr。现在我可以开始了,再次感谢。adarshr您能告诉我如何调用notify()我的意思是我需要用thread1打印1-3,然后thread1必须去等待()现在thread2应该打印所有5个数字,然后再打印thread1需要打印剩余的…实际上我对threads是新手,我在网上看到了很多例子,但有很多困惑,但是你的解释真的很好,我理解了这个概念,请做这个帮助谢谢。