我听说,sleep()将锁定当前的同步方法/块 但是在这里,当我在线程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应该正确启动? 问题是什么?
答案 0 :(得分:9)
这是因为你在这里有两个不同的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();
}
答案 1 :(得分:2)
睡眠,产量和加入规则
睡眠用于延迟执行一段时间,并且没有锁定 线程进入休眠状态时释放。
保证睡眠线程至少在指定的时间内休眠 sleep()方法的参数(除非它被中断),但是有 无法保证新唤醒的线程何时会实际返回 运行强>
sleep()方法是一个静态方法,用于休眠当前正在执行的操作 线程的状态。一个线程无法告诉另一个线程休眠。
setPriority()方法用于Thread对象以提供线程 优先级介于1(低)和10(高)之间,但优先级不是 保证,并非所有JVM都识别10个不同的优先级 - 一些 水平可以被视为有效平等。
如果没有明确设置,线程的优先级将具有相同的优先级 创建它的线程的优先级。
如果存在,yield()方法可能会导致正在运行的线程退出 具有相同优先级的可运行线程。无法保证这一点 发生了,并且无法保证线程在那里退出 将是一个选择运行的不同线程。一个线程可能会产生然后 立即重新进入运行状态。
最接近保证的是在任何给定时间,当一个线程 正在运行它通常没有比任何线程更低的优先级 可运行的状态。如果低优先级线程在高优先级线程时运行 进入runnable后,JVM通常会抢占正在运行的低优先级 线程并将高优先级线程放入。
当一个线程调用另一个线程的join()方法时,当前 正在运行的线程将一直等到它加入的线程完成。认为 join()方法的说法,&#34;嘿线程,我想加入到最后 你的。让我知道你什么时候完成,所以我可以进入可运行状态。&#34;
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
答案 2 :(得分:0)
您创建了两个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();
}
}
}
} }