微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

程序在多线程环境中未终止-Java

如何解决程序在多线程环境中未终止-Java

尝试制作一个简单的多线程程序,它打印因子系列,其中每个数字由不同的线程打印,最后我给出了哪个线程打印的数字的报告。我得到了所需的输出,但不知何故我的程序没有终止。

约束:我不能使用并发包

import java.util.ArrayList;
import java.util.Scanner;

class Report {

  private long factorial;
  private String threadName;
  private int activeThreads;

  public Report(long factorial,String threadName,int activeThreads) {
      this.factorial = factorial;
      this.threadName = threadName;
      this.activeThreads = activeThreads;
  }

  public long getFactorial() {
      return factorial;
  }

  public String getThreadName() {
      return threadName;
  }

  public int getActiveThreads() {
      return activeThreads;
  }

  public void setActiveThreads(int activeThreads) {
      this.activeThreads = activeThreads;
  }

}

public class Factorial implements Runnable {

  public static ArrayList<Report> report = new ArrayList<Report>();
  private static int count;

  public static void main(String[] args) throws InterruptedException {

      Scanner in = new Scanner(system.in);

      System.out.print("N: ");
      int n = in.nextInt();
    
      count = n;
    
      Factorial f = new Factorial();
      f.series(n);
    
      Thread.sleep(1000);
    
      // Series
      for(Report r : report) {
          if(r.getFactorial() == 1) {
              System.out.print(r.getFactorial());
          }
          else {
              System.out.print(r.getFactorial() + "*");
          }
      }
    
      System.out.println();
    
      // Report
      for(Report r : report) {
          System.out.println(r.getFactorial() + " printed by " + r.getThreadName() + " " + r.getActiveThreads());
      }
      ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
      System.out.println("In Main");
    
      in.close();
  }

  public void series(int n) throws InterruptedException {
      for(int i=0;i<n;i++) {
          Thread t = new Thread(new Factorial());
          t.start();
      }
  }

  public synchronized void generate() {
      ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
      report.add(new Report(count--,Thread.currentThread().getName(),threadGroup.activeCount()));
      notifyAll();
      System.out.println("In generate" + threadGroup.activeCount());
  }
    


  @Override
  public void run() {
      generate();
      synchronized (this) {
          try {
              wait();
          }
          catch(Exception e) {
              e.printstacktrace();
          }
      }
      ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
      System.out.println("In Run" + threadGroup.activeCount());
  }

  public static int getCount() {
      return count;
  }

  public static void setCount(int count) {
      Factorial.count = count;
  }

}

虽然我知道我们可以使用 .stop() 杀死线程,但我认为不推荐这样做。

解决方法

要使同步有效(synchronizedwaitnotify),您必须使用相同的实例。
series 中,您在每个循环中创建一个新的 Factorial 实例,使每个线程无限期地等待。

public void series(int n) throws InterruptedException {
  for(int i=0;i<n;i++) {
      // Thread t = new Thread(new Factorial()); // creates an new instance
      Thread t = new Thread(this);
      t.start();
  }
}

run 方法中,您首先调用 notifyAll()(通过 generate),然后调用 wait
最后创建的线程将在所有其他线程完成后wait
无论如何,必须通知最后一个线程。 可能就在 sleep 调用之后,使用:

synchronized(f) {
    f.notify();
}

或者可能使用专用的同步方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。