无法正确中断 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
所以基本上我的程序使用 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