无法正确中断 Avg 线程

Unable to interrupt Avg threads properly

所以基本上我的程序使用 Avg 线程从生成器获取数字,从中计算平均值并将它们发送到收集器。我想在工作 10 秒后中断所有线程,但即使生成器和控制器运行正常,我似乎也无法以与前者相同的方式中断 Avg 线程。你能给我一些关于为什么他们不会终止的见解吗?

import java.util.Scanner;

    public class ElaboratoEsame {


    public static void main(String[] args) {
        int N ;
        int M ;
        Scanner scanner = new Scanner(System.in);
        System.out.println("Inserire il numero dei Thread Avg");
        N=scanner.nextInt();
        System.out.println("Inserire M");
        M=scanner.nextInt();
        scanner.close();

        Monitor1 m1 = new Monitor1(N);
        Monitor2 m2 = new Monitor2(N);

        Generator g = new Generator(m1);
        g.start();

        Collector c = new Collector(m2, N);
        c.start();

        Avg[] avg = new Avg[N];
        for (int i = 0; i < N; i++) {
            avg[i] = new Avg(i, m1, m2, M);
            avg[i].start();
        }

        try{
            Thread.sleep(2*1000);
        }catch(InterruptedException ie) {}

        g.interrupt();
        for (int i=0; i > N; i++){
            avg[i].interrupt();
        }        
        c.interrupt(); 
        try{Thread.sleep(500);

        }catch(InterruptedException ie){}
        System.out.println(g.isAlive());
    }
}   

public class Generator extends Thread {

    private final Monitor1 m1;

    public Generator(Monitor1 m1) {
        this.m1 = m1;
    }

    @Override
    public void run() {
        int i = 0;
        try {
            do {
                m1.doWrite(i);
                ++i;
                Thread.sleep(100);
            } while (true);
        } catch (InterruptedException ie) {
            System.out.println("Generator is interrupted");
        }
    }
}

public class Monitor1 {
    private final Integer[] numbers;
    private int index = 0;

    public Monitor1(int N){
        numbers = new Integer[N];
    }

    public synchronized int doRead(int id) throws InterruptedException{
        while(numbers[id]==null){
            wait();
        }
        int result=numbers[id];
        numbers[id]=null;
        notifyAll();
        return result;
    }

    public synchronized void doWrite(int i) throws InterruptedException{
        while(numbers[index]!=null){
            wait();
        }
        numbers[index]=i;
        index=(index+1)%(numbers.length);
        notifyAll();
    }



}

public class Avg extends Thread {

    private final int id;
    private final Monitor1 m1;
    private final Monitor2 m2;
    private final int M;

    public Avg(int id, Monitor1 m1, Monitor2 m2, int M) {
        this.id = id;
        this.m1 = m1;
        this.m2 = m2;
        this.M = M;
    }

    @Override
    public void run() {
        try {
            do {
                double sum = 0;
                for (int i = 0; i < M; ++i) {
                    sum += m1.doRead(id);
                }
                double avg = sum / M;
                System.out.println("Avg " + id + " : " + avg);
                m2.doWrite(id, avg);
            } while (true);            
        } catch (InterruptedException ie) {
            System.out.println("Avg " + id + " is interrupted");
        }
    }


}

public class Monitor2 {
    private final Double[] averages;


    public Monitor2(int N){
        averages = new Double[N];
    }

    public synchronized double doRead(int i) throws InterruptedException{
        while(averages[i]==null){
            wait();
        }
        double result=averages[i];
        averages[i]=null;
        notifyAll();
        return result;        
    }

    public synchronized void doWrite(int id, double avg) throws InterruptedException{
        while(averages[id]!=null){
            wait();
        }
        averages[id]=avg;
        notifyAll();

    }
}
public class Collector extends Thread{
    private final Monitor2 m2;
    private final int N;

    public Collector (Monitor2 m2, int N){
        this.m2=m2;
        this.N=N;
    }

    @Override
    public void run(){
        try{
            do{
                double sum=0;
                for (int i = 0; i < N; ++i) {
                    sum += m2.doRead(i);
                }
                System.out.println("La somma è " + sum);
            }while(true);
        }catch(InterruptedException ie){
            System.out.println("Collector is interrupted");
        }

    }
}

调用 avg 中断的循环中存在错误。尝试改变这个 -

for (int i=0; i > N; i++){
    avg[i].interrupt();
}  

到这个-

for (int i=0; i < N; i++){
    avg[i].interrupt();
}  

我建议使用 ExecutorService 来处理线程管理,API 有很多精致的方法可以帮助,基本上,你会做的是:

    int NUM_OF_THREADS = 10;
    ExecutorService executor = Executors.newFixedThreadPool(NUM_OF_THREADS);
    List<Future> futures = new ArrayList<Future>();
    for (int i = 0; i < NUM_OF_THREADS; i++){
        futures.add(executor.submit(new Runnable() {

            @Override
            public void run() {
                System.out.println("Test");
            }
        }));
    }
    //first possibility is to cancel each task
    for (Future f: futures){
        f.cancel(true);
    }
    //second possibility is to shut down the executor
    executor.shutdownNow();

有关详细信息,请参阅 JavaDoc:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html