使用睡眠和中断的Java多线程 类无用{ 公共静态布尔值b=true; 公共同步的void u1(){ 试一试{ while(b==true) 等待(); }捕获(中断异常i){ } } 公共同步的void u2(){ 如果(b==true){ b=假; } 通知(); } } 公共类SleepMessages扩展线程{ 私人无用u; 公共睡眠信息(u){ 这个。u=u; } 公开募捐{ 字符串importantInfo[]={“母马吃燕麦”,“确实吃燕麦”}; for(int i=0;i
这个小程序的输出给出: 他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗 我的问题是,为什么线程t2是唯一一个进入catch(InterruptedException e)的线程,为什么结果不是这样的: 他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗 我的问题是为什么线程t2是唯一进入catch(InterruptedException e)的线程 在我看来,使用睡眠和中断的Java多线程 类无用{ 公共静态布尔值b=true; 公共同步的void u1(){ 试一试{ while(b==true) 等待(); }捕获(中断异常i){ } } 公共同步的void u2(){ 如果(b==true){ b=假; } 通知(); } } 公共类SleepMessages扩展线程{ 私人无用u; 公共睡眠信息(u){ 这个。u=u; } 公开募捐{ 字符串importantInfo[]={“母马吃燕麦”,“确实吃燕麦”}; for(int i=0;i,java,multithreading,synchronization,sleep,interrupt,Java,Multithreading,Synchronization,Sleep,Interrupt,这个小程序的输出给出: 他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗 我的问题是,为什么线程t2是唯一一个进入catch(InterruptedException e)的线程,为什么结果不是这样的: 他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗 我的问题是为什么线程t2是唯一进入catch(InterruptedException e)的线程 在我看来,t1.interrupt()正在中断run()方法中的睡眠。一旦您放弃了InterruptedExcep
t1.interrupt()
正在中断run()方法中的睡眠。一旦您放弃了InterruptedException,就无法知道该线程以前被中断过
为什么结果不是这样的:
他们来了!。。。母马吃燕麦-t1母马吃燕麦-t2吃燕麦-t1吃燕麦-t2
Java使用有偏锁定。这意味着获取锁的最后一个线程更有可能首先获取相同的锁。只有一个无用实例,因此只有一个布尔b。设置为true后,SleepMessages的两个实例都可以离开等待循环,因此,如果多个CPU同时运行线程,则无论哪一个实例有机会运行,还是两个实例都将运行。当我测试代码时,两个线程都被中断,没有问题,所以我不知道你为什么认为其中任何一个都没有进入捕捉区 这个练习似乎是第一次使用中断(触发线程打印其第一条消息),第二次设置布尔值
b
(触发第二条消息),从而打破在u1()中的等待
对于interrupt()
对于u2()
部分,顺序的可预测性要低得多。t1
和t2
都在同一个监视器上等待。notify()
调用可能会唤醒其中一个。醒来的人打印第二条信息,再睡一会儿,然后停下来。第二个notify()
因此,最后两条消息的顺序是不确定的
最后一点建议:您似乎想要实现的行为可能更容易使用实现。我已经完成了,我在run方法上添加了一个system.out.println,如果线程是否输入了catch,结果是只有线程t2输入了该catch,t1也被中断,但,它没有进入catch并在睡眠中卡住..您是否向两个catch块(即在run()中)都添加了log语句?是的,我指的是run中的catch块。只有线程t2在run方法中进入catch块,您可以在u1
中的catch块中添加日志吗?这样做,似乎在u1中只有线程t1进入catch块,所以基本上每个线程都进入不同的catch块,这是为什么?
class Useless {
public static boolean b = true;
public synchronized void u1() {
try {
while (b == true)
wait();
} catch (InterruptedException i) {
}
}
public synchronized void u2() {
if (b == true) {
b = false;
}
notify();
}
}
public class SleepMessages extends Thread {
private Useless u;
public SleepMessages(Useless u) {
this.u = u;
}
public void run() {
String importantInfo[] = { "Mares eat oats", "Does eat oats" };
for (int i = 0; i < importantInfo.length; i++) {
u.u1();
System.out.println(importantInfo[i] + " - " + getName());
try {
sleep(2000);
} catch (InterruptedException e) {
}
}
}
public static void main(String args[]) throws InterruptedException {
Useless u = new Useless();
Thread t1 = new SleepMessages(u);
t1.setName("t1");
Thread t2 = new SleepMessages(u);
t2.setName("t2");
t1.start();
t2.start();
sleep(2000);
System.out.println("Here they go!...");
t1.interrupt();
sleep(1000);
t2.interrupt();
u.u2();
sleep(1000);
u.u2();
}
}