Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最后一个线程未执行_Java_Multithreading - Fatal编程技术网

Java 最后一个线程未执行

Java 最后一个线程未执行,java,multithreading,Java,Multithreading,我对多线程非常陌生,我尝试了一个场景,在这个场景中,一个家庭有一个母亲(作为生产者)、儿子、女儿和丈夫(作为消费者)线程。我试图理解wait和notify方法在这方面的帮助 我的课程如下 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 prepar

我对多线程非常陌生,我尝试了一个场景,在这个场景中,一个家庭有一个母亲(作为生产者)、儿子、女儿和丈夫(作为消费者)线程。我试图理解wait和notify方法在这方面的帮助

我的课程如下

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
母性生产者 索纳消费类 子母阶层 HusbandAsConsumer类 家庭课 我的输出是不同的,每次都是线程的性质所期望的,但其中一个人,无论是丈夫、女儿还是儿子,都没有完成。 我的输出的一个实例如下

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
我的理解是当儿子、女儿和丈夫开始执行时,其中一个会点击synchronized方法并执行wait()并保持锁,再次从该同步方法调用另一个同步方法,该方法将包含notify,锁将被释放,另一个线程将尝试从被阻止的池中获取锁,并将以相同的方式执行。这里有两个线程按预期运行,但最后一个线程没有。
请在此提供帮助。

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

也就是说,如果线程A最初获得锁,那么它将执行println和sleep,然后执行println,然后通知所有等待的线程(没有),然后成为等待的线程

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

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

这有意义吗?我误读了什么吗

要验证我的建议是否错误,只需添加更多线程。你应该总是让最后一个印着“Chapati是为……准备的”的人永远不会吃它

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


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

将枚举类MotherAsProducer中的方法更改如下:不必要的wait()方法导致了问题。由于该方法是同步的,所以在进入该方法之前,所有其他线程都将被阻塞,直到收到锁持有线程的通知为止

公共同步的void takeOrderAndMakeChapati(){


takeOrderAndMakeChapati
getStatusOfChapati
中删除
wait
notifyAll
调用。您将获得预期结果

正如Josh精确提到的,其中一个线程(最后一个)仍在等待一些外部通知,并且没有人要通知。您的代码仍在后台运行。只需调用
wait(5000)
,您就可以看到它正在发生

两种方法
takeOrderAndMakeChapati
getStatusOfChapati
都是同步的,因此同步不是问题


通常,线程
等待
某些外部依赖项或条件,其中一些其他线程当该条件满足时通知等待者。

我在开始使用多线程时也试图理解
wait
notify
。但当我学会使用a时,我就再也没有回头看。希望下面的示例能让您了解使用信号量的好处。还有很多其他原因e包装中有用的东西,可以提供很大帮助

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class EatChapati {

static int CHAPATI_PREPARE_TIME_MS = 100;
static long RUN_TIME_MS = 2000;
static long SHUTDOWN_TIME_MS = 500;
static int CHAPATI_CONSUMERS = 5;
static volatile boolean stop;

public static void main(String[] args) {

    ExecutorService executor = Executors.newCachedThreadPool();
    for (int i = 0; i < CHAPATI_CONSUMERS; i++) {
        executor.execute(new ChapatiConsumer(i + 1));
    }
    try { Thread.sleep(RUN_TIME_MS); } catch (Exception ignored) {}
    stop = true;
    executor.shutdownNow();
    try { executor.awaitTermination(SHUTDOWN_TIME_MS, TimeUnit.MILLISECONDS); } catch (Exception ignored) {}
}

// 1 producer making chapati's
// 'true' for a fair semaphore: longest waiting consumer gets served 
static Semaphore chapatiTurn = new Semaphore(1, true);
static AtomicInteger chapatiCount = new AtomicInteger();

static int getChapati(int consumerNumber) {

    int chapatiNumber = 0;
    boolean haveTurn = false;
    try {
        chapatiTurn.acquire();
        // start of 'synchronized' block
        haveTurn = true;
        Thread.sleep(CHAPATI_PREPARE_TIME_MS);
        chapatiNumber = chapatiCount.incrementAndGet();
        System.out.println("Chapati " + chapatiNumber + " prepared for consumer " + consumerNumber);
    } catch (Exception e) {
        // Triggered by executor.shutdownNow
        stop = true;
    } finally {
        if (haveTurn) {
            chapatiTurn.release();
            // end of 'synchronized' block
        }
    }
    return chapatiNumber;
}

static class ChapatiConsumer implements Runnable {

    int number;

    ChapatiConsumer(int number) {
        this.number = number;
    }

    public void run() {

        int chapatisConsumed = 0;
        while (!stop) {
            if (getChapati(number) > 0) {
                chapatisConsumed++;
            }
        }
        System.out.println("Consumer " + number + " stopped after consuming " + chapatisConsumed + " chapatis.");
    }
}
}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Semaphore;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.AtomicInteger;
公共课{
静态int CHAPATI_PREPARE_TIME_MS=100;
静态长期运行时间=2000;
静态长停机时间\u MS=500;
静态int CHAPATI_消费者=5;
静态可变布尔停止;
公共静态void main(字符串[]args){
ExecutorService executor=Executors.newCachedThreadPool();
对于(int i=0;ipackage 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
    System.out.println("Request got from "  + Thread.currentThread().getName());
    getStatusOfChapati();
   // wait(); - THIS WAIT IS CAUSING THE PROBLEM
    System.out.println(Thread.currentThread().getName()  + " ate chapati");
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class EatChapati {

static int CHAPATI_PREPARE_TIME_MS = 100;
static long RUN_TIME_MS = 2000;
static long SHUTDOWN_TIME_MS = 500;
static int CHAPATI_CONSUMERS = 5;
static volatile boolean stop;

public static void main(String[] args) {

    ExecutorService executor = Executors.newCachedThreadPool();
    for (int i = 0; i < CHAPATI_CONSUMERS; i++) {
        executor.execute(new ChapatiConsumer(i + 1));
    }
    try { Thread.sleep(RUN_TIME_MS); } catch (Exception ignored) {}
    stop = true;
    executor.shutdownNow();
    try { executor.awaitTermination(SHUTDOWN_TIME_MS, TimeUnit.MILLISECONDS); } catch (Exception ignored) {}
}

// 1 producer making chapati's
// 'true' for a fair semaphore: longest waiting consumer gets served 
static Semaphore chapatiTurn = new Semaphore(1, true);
static AtomicInteger chapatiCount = new AtomicInteger();

static int getChapati(int consumerNumber) {

    int chapatiNumber = 0;
    boolean haveTurn = false;
    try {
        chapatiTurn.acquire();
        // start of 'synchronized' block
        haveTurn = true;
        Thread.sleep(CHAPATI_PREPARE_TIME_MS);
        chapatiNumber = chapatiCount.incrementAndGet();
        System.out.println("Chapati " + chapatiNumber + " prepared for consumer " + consumerNumber);
    } catch (Exception e) {
        // Triggered by executor.shutdownNow
        stop = true;
    } finally {
        if (haveTurn) {
            chapatiTurn.release();
            // end of 'synchronized' block
        }
    }
    return chapatiNumber;
}

static class ChapatiConsumer implements Runnable {

    int number;

    ChapatiConsumer(int number) {
        this.number = number;
    }

    public void run() {

        int chapatisConsumed = 0;
        while (!stop) {
            if (getChapati(number) > 0) {
                chapatisConsumed++;
            }
        }
        System.out.println("Consumer " + number + " stopped after consuming " + chapatisConsumed + " chapatis.");
    }
}
}