简体   繁体   English

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

[英]Java Thread synchronization - Thread.sleep() Method Not Working as desired

i heard, sleep() will lock the current sync method/block But here, when i call sleep() on thread 1, thread 2 is able to access the same block? 我听说,sleep()将锁定当前的sync方法/块但是在这里,当我在线程1上调用sleep()时,线程2能够访问同一个块吗? Can anyone Explain? 谁能解释一下吗?

Main.java 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();

    }

}

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

Thread1.java Thread1.java

public class Thread1 extends Thread{

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

}

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

Thread2.java Thread2.java

public class Thread2 extends Thread{

    public void run() { 
        Syncc s2 = new Syncc();
        s2.me("T2:");
    }   
}

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

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

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

Output: 输出:

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

BUT according to sleep() method, it should not unlock the current synchronization block right? 但是根据sleep()方法,它不应该解锁当前的同步块吗? if so the out put should be.. 如果是这样,输出应该是......

going to start t1 going to start t2 将开始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

i mean after thread 1 execution only thread 2 should start right? 我的意思是在线程1执行后,只有线程2应该正确启动? Whats the issue? 问题是什么?

This is because you have two different instances of Syncc in play here. 这是因为您在此处有两个不同的Syncc实例。 Each thread has its own copy of Syncc . 每个线程都有自己的Syncc副本。

Try doing the same with a single instance. 尝试对单个实例执行相同操作。 You could also synchronize on the static context and try. 您还可以在静态上下文中进行同步并尝试。

To simulate, modify Thread1 and Thread2 to accept an instance of 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:");
    }   
}

You can then start them as so: 然后您可以这样启动它们:

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

Rules of Sleep, Yield and Join 睡眠,产量和加入规则

  • Sleeping is used to delay execution for a period of time, and no locks are released when a thread goes to sleep. 休眠用于延迟执行一段时间,并且当线程进入休眠状态时不释放锁定。

  • A sleeping thread is guaranteed to sleep for at least the time specified in the argument to the sleep() method (unless it's interrupted), but there is no guarantee as to when the newly awakened thread will actually return to running. 保证睡眠线程至少在sleep()方法的参数中指定的时间内休眠(除非它被中断), 但不能保证新唤醒的线程何时实际返回运行状态。

  • The sleep() method is a static method that sleeps the currently executing thread's state. sleep()方法是一个静态方法,它休眠当前正在执行的线程的状态。 One thread cannot tell another thread to sleep. 一个线程无法告诉另一个线程睡眠。

  • The setPriority() method is used on Thread objects to give threads a priority of between 1 (low) and 10 (high), although priorities are not guaranteed, and not all JVMs recognize 10 distinct priority levels—some levels may be treated as effectively equal. setPriority()方法用于Thread对象,为线程提供1(低)到10(高)之间的优先级,虽然不保证优先级,并且并非所有JVM都能识别10个不同的优先级 - 某些级别可以被视为有效等于。

  • If not explicitly set, a thread's priority will have the same priority as the priority of the thread that created it. 如果未明确设置,则线程的优先级将与创建它的线程的优先级具有相同的优先级。

  • The yield() method may cause a running thread to back out if there are runnable threads of the same priority. 如果存在具有相同优先级的可运行线程,则yield()方法可能会导致正在运行的线程退出。 There is no guarantee that this will happen, and there is no guarantee that when the thread backs out there will be a different thread selected to run. 无法保证会发生这种情况,并且无法保证在线程退出时会选择运行不同的线程。 A thread might yield and then immediately reenter the running state. 线程可能会产生然后立即重新进入运行状态。

  • The closest thing to a guarantee is that at any given time, when a thread is running it will usually not have a lower priority than any thread in the runnable state. 最接近保证的是,在任何给定时间,当线程运行时,它通常不会比可运行状态中的任何线程具有更低的优先级。 If a low-priority thread is running when a high-priority thread enters runnable, the JVM will usually preempt the running low-priority thread and put the high-priority thread in. 如果在高优先级线程进入runnable时正在运行低优先级线程,则JVM通常会抢占正在运行的低优先级线程并将高优先级线程置于其中。

  • When one thread calls the join() method of another thread, the currently running thread will wait until the thread it joins with has completed. 当一个线程调用另一个线程的join()方法时,当前运行的线程将一直等到它加入的线程完成。 Think of the join() method as saying, "Hey thread, I want to join on to the end of you. Let me know when you're done, so I can enter the runnable state." 想想join()方法就是这样说的,“嘿线程,我想加入到你的最后。让我知道你什么时候完成,所以我可以进入runnable状态。”

http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060 http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060

You have created two Synch objects each object corresponding to one thread . 您已创建两个Synch对象,每个对象对应一个线程。 Each object has its own copy of me. 每个对象都有自己的副本。 Hence when your start each thread, withing the run method the thread is calling its own copy of the function me. 因此,当你启动每个线程时,使用run方法线程正在调用它自己的函数副本。 Since the two thread act only on their copy this works like a single thread scenario. 由于两个线程只在它们的副本上起作用,因此它就像一个单线程场景。 If you do want to test a multithread scenario then make the method me static(class level method) and apply a class level lock. 如果您确实想测试多线程场景,那么请将该方法设为静态(类级方法)并应用类级锁。

Thread1.java Thread1.java

public class Thread1 extends Thread{

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

} }

Thread2.java Thread2.java

public class Thread2 extends Thread{

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

} }

Syncc.java Syncc.java

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

} } }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM