java - 最后一个线程没有执行

标签 java multithreading

我是多线程的新手,正在尝试一个家庭有母亲(作为生产者)、儿子、女儿和丈夫[作为消费者]线程的场景。我试图了解等待和通知方法在这里有何帮助.

我的类(class)如下。

MotherAsProducer

package com.test.All.Threads;

public enum MotherAsProducer {

INSTANCE;

    /*
     * 
     * 
     * son Give request to prepare chapati to mother
     * mother accepts it and start preparing , son/husband/daughter should wait by that time.
     * mother notifies son/daughtor/husband that chapati is ready start consuming
     * */


    public synchronized void  takeOrderAndMakeChapati(){

        try {
            System.out.println("Request got from "+Thread.currentThread().getName());
            getStatusOfChapati();
            wait();
            System.out.println(Thread.currentThread().getName()+" ate chapati");

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //lock re-entrance
    public  synchronized void getStatusOfChapati(){

        try {
            Thread.sleep(1200);
            System.out.println("Chapati is prepared for "+Thread.currentThread().getName());
            notifyAll();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static MotherAsProducer getMotherInstance(){

        return MotherAsProducer.INSTANCE;
    }
}

SonAsConsumer 类

package com.test.All.Threads;

public class SonAsConsumer implements Runnable{

    public void run(){

            MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();

    }

}

DaughterAsConsumer 类

package com.test.All.Threads;

public class DaughterAsConsumer implements Runnable {

    public void run(){

        MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();

    }

}

HusbandAsConsumer 类

package com.test.All.Threads;

public class HusbandAsConsumer implements Runnable {

    public void run(){

        MotherAsProducer.getMotherInstance().takeOrderAndMakeChapati();
    }

}

家课

package com.test.All.Threads;

public class Home {

    public static void main(String args[]){

        SonAsConsumer sac = new SonAsConsumer();
        DaughterAsConsumer dac = new DaughterAsConsumer();
        HusbandAsConsumer hac = new HusbandAsConsumer();

        Thread tsac = new Thread(sac);
        tsac.setName("Son");
        Thread tdac = new Thread(dac);
        tdac.setName("Daughter");
        Thread thac = new Thread(hac);
        thac.setName("Husband");


        tsac.start();
        tdac.start();
        thac.start();
    }
}

我的输出是不同的,每次都符合线程的性质,但其中一个丈夫、女儿或儿子没有完成。 我的输出的一个实例如下。

Order she got from Daughter
Chapati is prepared for Daughter
Order she got from Son
Chapati is prepared for Son
Order she got from Husband
Chapati is prepared for Husband
Son ate chapati
Daughter ate chapati

我的理解是,当儿子、女儿和丈夫开始执行其中一个时,他们将命中同步方法并执行 wait() 并持有锁,再次从该同步方法调用另一个同步方法,其中将包含通知和锁将被释放,另一个线程将尝试从阻塞池中获取锁并以相同的方式执行。这里有两个线程的行为符合预期,但最后一个不是。 请在这里提供帮助。

最佳答案

简单地看一下,最后一个等待的线程似乎永远不会收到通知。对你的调用进行排序,你让每个线程都获得一个锁,通知所有等待的线程,然后等待。因此,最后一个等待的线程永远不会有人通知他们需要退出。

也就是说,如果线程A一开始就拿到了锁,那么它会做一个println和一个sleep然后一个println,然后通知所有等待的线程(没有),然后成为一个等待线程。

然后,假设线程 B 获得了锁。它会执行一个 println 和一个 sleep ,然后它会通知所有(这将“通知”线程 A),然后它会等待。

现在,线程 C 或线程 A 将获得锁。如果线程 A 得到它,它将简单地失败并以“吃”消息完成。然后,线程 C 可以获得锁,它最终会通知,唤醒 B 一旦 C“等待”就可以吃东西。现在,没有线程可以通知 C 将完成。

这有道理吗?我是不是看错了什么?

要验证我的建议是错误的,只需添加更多线程即可。你应该永远让最后一个打印“Chapati is prepared for ...”的人永远不会吃掉它。

从根本上说,我认为混淆是“母亲”实际上没有做任何工作。您可能想要的是让“Mother”成为一个拥有自己的工作日志的线程。因此,当其他线程之一给她工作时,您设置一个变量然后通知母亲并作为 sibling 等待。然后母亲会醒来并做工作并通知当前线程等待。

明白我的意思了吗?打个比方,这个项目中有 4 个人。但是,您只有 3 个线程。

关于java - 最后一个线程没有执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24654187/

相关文章:

java - class.getMethod() 在我的上下文中不起作用

java - EJB3 bean 中的可选注入(inject)或运行时依赖性检查

Java删除字符串问题(请不要使用StringBuilder或BufferedWriter给出任何解决方案)

java - 确定fx :id of a pressed button

JavaFX-ProviderNotFoundException : Provider not found

Python在线程定时器中运行SQL语句

sql - Grails 服务中的数据源注入(inject)

Java 线程(竞争条件)

JavaScript 同步 Ajax 请求特性

java - 主 Java 线程终止时如何管理工作线程生命周期?