程序在多线程环境中不终止 -Java
Programme not Terminating in Multi-threaded environment -Java
尝试制作一个简单的多线程程序,它打印阶乘系列,其中每个数字由不同的线程打印,最后我给出一个报告,其中 thread.I 打印了哪个数字所需的输出,但不知何故我的程序没有终止。
约束:不允许我使用并发包
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() 终止线程,但我认为不推荐这样做。
要使同步生效(synchronized
、wait
、notify
),您必须使用相同的实例。
在 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();
}
或者可能使用专用的同步方法。
尝试制作一个简单的多线程程序,它打印阶乘系列,其中每个数字由不同的线程打印,最后我给出一个报告,其中 thread.I 打印了哪个数字所需的输出,但不知何故我的程序没有终止。
约束:不允许我使用并发包
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() 终止线程,但我认为不推荐这样做。
要使同步生效(synchronized
、wait
、notify
),您必须使用相同的实例。
在 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();
}
或者可能使用专用的同步方法。