使用睡眠和中断的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多线程 类无用{ 公共静态布尔值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

这个小程序的输出给出: 他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗

我的问题是,为什么线程t2是唯一一个进入catch(InterruptedException e)的线程,为什么结果不是这样的:

他们来了!。。。 母马吃燕麦 母马吃燕麦 你吃燕麦吗 你吃燕麦吗

我的问题是为什么线程t2是唯一进入catch(InterruptedException e)的线程

在我看来,
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();
    }
}