[英]Java Thread synchronization - Thread.sleep() Method Not Working as desired
我听说,sleep()将锁定当前的sync方法/块但是在这里,当我在线程1上调用sleep()时,线程2能够访问同一个块吗? 谁能解释一下吗?
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();
}
}
================================================== ===================
public class Thread1 extends Thread{
public void run() {
Syncc s1 = new Syncc();
s1.me("T1:");
}
}
================================================== ===================
public class Thread2 extends Thread{
public void run() {
Syncc s2 = new Syncc();
s2.me("T2:");
}
}
================================================== ===================
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();
}
}
}
}
}
==========================================
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
但是根据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
副本。
尝试对单个实例执行相同操作。 您还可以在静态上下文中进行同步并尝试。
为了模拟,修改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()方法用于Thread对象,为线程提供1(低)到10(高)之间的优先级,虽然不保证优先级,并且并非所有JVM都能识别10个不同的优先级 - 某些级别可以被视为有效等于。
如果未明确设置,则线程的优先级将与创建它的线程的优先级具有相同的优先级。
如果存在具有相同优先级的可运行线程,则yield()方法可能会导致正在运行的线程退出。 无法保证会发生这种情况,并且无法保证在线程退出时会选择运行不同的线程。 线程可能会产生然后立即重新进入运行状态。
最接近保证的是,在任何给定时间,当线程运行时,它通常不会比可运行状态中的任何线程具有更低的优先级。 如果在高优先级线程进入runnable时正在运行低优先级线程,则JVM通常会抢占正在运行的低优先级线程并将高优先级线程置于其中。
当一个线程调用另一个线程的join()方法时,当前运行的线程将一直等到它加入的线程完成。 想想join()方法就是这样说的,“嘿线程,我想加入到你的最后。让我知道你什么时候完成,所以我可以进入runnable状态。”
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
您已创建两个Synch对象,每个对象对应一个线程。 每个对象都有自己的副本。 因此,当你启动每个线程时,使用run方法线程正在调用它自己的函数副本。 由于两个线程只在它们的副本上起作用,因此它就像一个单线程场景。 如果您确实想测试多线程场景,那么请将该方法设为静态(类级方法)并应用类级锁。
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
}
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
}
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.