Java程序不会停止
我有一个大小为n的数组,其中填充了数字1..n 我需要使用m个线程对这个数组求和,每次取两个元素,求和并将求和插入到数组中 这就是我试图做的 首先是同步部分Java程序不会停止,java,multithreading,Java,Multithreading,我有一个大小为n的数组,其中填充了数字1..n 我需要使用m个线程对这个数组求和,每次取两个元素,求和并将求和插入到数组中 这就是我试图做的 首先是同步部分 public class MultiThreadedSum { private ArrayBuffer ArrayBufferInst; private int Sum; private boolean Flag, StopFlag; public MultiThreadedSum(ArrayBuffer
public class MultiThreadedSum {
private ArrayBuffer ArrayBufferInst;
private int Sum;
private boolean Flag, StopFlag;
public MultiThreadedSum(ArrayBuffer ArrayBufferInst) {
this.ArrayBufferInst = ArrayBufferInst;
Sum = 0;
Flag = false;
StopFlag = false;
}
public synchronized void Sum2Elements() {
while(Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = true;
if (StopFlag) {
notifyAll();
return;
}
System.out.println("Removing and adding 2 elements.");
Sum = ArrayBufferInst.Sum2Elements();
notifyAll();
}
public synchronized void InsertElement() {
while(!Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = false;
if (StopFlag) {
notifyAll();
return;
}
System.out.println("Inserting the sum.");
ArrayBufferInst.InsertElement(Sum);
if (ArrayBufferInst.RetunrSize() == 1) {
StopFlag = true;
}
System.out.println(ArrayBufferInst);
notifyAll();
}
public boolean ReturnStopFlag(){
return StopFlag;
}
@Override
public String toString(){
return ArrayBufferInst.toString();
}
}
我已经将m个线程分为两组,其中一半将进行总结,另一半将使用wait和notify进行添加
public class Sum2ElementsThread implements Runnable{
private MultiThreadedSum MultiThreadedSumInst;
public Sum2ElementsThread( MultiThreadedSum MultiThreadedSumInst){
this.MultiThreadedSumInst = MultiThreadedSumInst;
}
@Override
public void run() {
while(!MultiThreadedSumInst.ReturnStopFlag())
MultiThreadedSumInst.Sum2Elements();
}
}
public class InsertThread implements Runnable{
private MultiThreadedSum MultiThreadedSumInst;
public InsertThread( MultiThreadedSum MultiThreadedSumInst) {
this.MultiThreadedSumInst = MultiThreadedSumInst;
}
@Override
public void run() {
while(!MultiThreadedSumInst.ReturnStopFlag()) {
MultiThreadedSumInst.InsertElement();
}
}
}
以下是主要问题的一部分:
ArrayBufferInst = new ArrayBuffer(n);
System.out.println("The Array");
System.out.println(ArrayBufferInst);
MultiThreadedSumInst = new MultiThreadedSum(ArrayBufferInst);
ExecutorService Threads = Executors.newCachedThreadPool();
for (i = 0; i < m/2; i++)
Threads.execute( new Sum2ElementsThread(MultiThreadedSumInst) );
for (; i < m; i++)
Threads.execute( new InsertThread(MultiThreadedSumInst) );
Threads.shutdown();
while(!MultiThreadedSumInst.ReturnStopFlag()){}
System.out.println("The sum of the array is " + MultiThreadedSumInst);
ArrayBufferInst=新的ArrayBuffer(n);
System.out.println(“数组”);
System.out.println(ArrayBufferInst);
MultiThreadedSumInst=新的多线程总和(ArrayBufferInst);
ExecutorService线程=Executors.newCachedThreadPool();
对于(i=0;i
缓冲区呢
public class ArrayBuffer {
private ArrayList<Integer> ArrayBufferInst;
public ArrayBuffer(int SizeOfBuffer){
int i;
ArrayBufferInst = new ArrayList<>(SizeOfBuffer);
for (i = 0; i < SizeOfBuffer; i++){
ArrayBufferInst.add(i, i+1);
}
}
public int Sum2Elements(){
if (ArrayBufferInst.size() < 2){
return -1;
}
return ArrayBufferInst.remove(0) + ArrayBufferInst.remove(0);
}
public void InsertElement(int Elem) {
ArrayBufferInst.add(Elem);
}
public int RetunrSize(){
return ArrayBufferInst.size();
}
@Override
public String toString() {
return ArrayBufferInst.toString();
}
}
公共类ArrayBuffer{
私人ArrayList ArrayBufferInst;
公共阵列缓冲区(int SizeOfBuffer){
int i;
ArrayBufferInst=新的ArrayList(SizeOfBuffer);
对于(i=0;i
我的问题是关于main的结尾,有时程序停止,有时不停止,我知道所有线程都在退出run方法,因为我检查了它
有时我会看到
数组的总和是
消息,有时我不会看到。对于您的任务来说,这确实是一个很长的代码
也许我可以提出一个不同的解决方案。
您可以将数组拆分为m个部分(m是线程的数量),每个线程将对自己的部分求和。当每个线程的求和结束时,只需求和所有部分的结果
或者我没有正确理解你的任务。请指定更多详细信息(完整任务)。您的问题在于:
public synchronized void Sum2Elements() {
while(Flag){
try {wait();}
catch (InterruptedException e){}
}
Flag = true;
// rest of method omitted here
}
当程序的这一部分第一次执行时,标志
为false,循环被忽略。此方法的所有后续执行都将导致死锁,因为这是唯一将标志设置为false的位置
即使是中断也不会起作用,因为循环中没有中断
,在中断后,您只需继续下一个循环,并永远等待()
哦,还有阅读——Java不是c#只是太多的代码需要为这个问题进行检查。您必须减少不必要的代码,以便更容易回答。@Siddharth您的第二条评论完全没有必要。我同意。我同意,但这是他们在作业中想要的,谢谢。好吧,我已经检查了所有线程是否完成了这些作业,我相信他们会完成。我相信一旦它启动,第一个线程将通过while,然后将flag设置为true,阻塞所有其他线程,同时在InsertElement中所有线程都已经在等待了。当该线程到达notifyAll()时,它将允许其中一个线程在InsertElement中执行相同的操作。我错了吗?谢谢