2017-02-24 95 views
2

因此,基本上我的程序与平均线程从Generator中获取数字一起工作,从中获取平均值并将它们发送到收集器。我想在工作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"); 
     } 

    } 
} 

回答

0

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

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

本 -

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

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

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