如何在 Java 中的循环中检查变量
How to check variable during a loop in Java
我知道这个问题之前可能有人问过,但我找不到任何主题,所以我打开这个。
在这段代码中,我有一个字符串 ArrayList (coda) 和一个字符串数组,我用它来拆分 ArrayList 的每个元素。在 for 的每次迭代中,我都会将一个元素提供给 class(WorkerRSR、WorkerLRSR 或两者),而那些 class 将执行不相关的操作。我想要的是在 for 的右大括号生效后执行 do-while。
Do-While 详细信息:
这是确保每个字符串都已被 classes 完全处理所必需的。在每个 运行 之后,每个 class 都会将变量编号增加 1,以便我知道所有元素何时完成。不幸的是,这样的 do-while 会冻结整个程序。
有没有办法在循环中检查变量?我知道我应该使用线程;我也检查了他们,但没有太大帮助..
//Let's pretend I have a fixed number or elements (3)
public static Semaphore sem = new Semaphore(-2,true);
[...]
if (src == execoda){
if (coda.size()==0){
JOptionPane.showMessageDialog(null,"La coda è vuota. Aggiungere elementi alla coda", "Attenzione",JOptionPane.INFORMATION_MESSAGE);
}
else{
System.out.println("inizio for "+sem.availablePermits());
codatof = false;
for (int i = 0; i<coda.size(); i++){
String[] tmp = ((String)coda.get(i)).split("-");
algo = tmp[6];
if(algo.equals("RSR")){
File[] folders = {new File(urlFrames+"\finalRSR"),};
folders[0].mkdir();
//parametri WorkerRSR: String urlImg, int dist, int numI, int spra, String algo (6), String urlFrames (7)
WorkerRSR workerRSR = new WorkerRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7]);
workerRSR.execute();
}
else if(algo.equals("LRSR")){
File[] folders = {new File(urlFrames+"\finalLRSR"),};
folders[0].mkdir();
//parametri WorkerLRSR: String urlImg, int dist, int numI, int spra, String algo, String urlFrames
WorkerLRSR workerLRSR = new WorkerLRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7],Integer.parseInt(tmp[4]),Integer.parseInt(tmp[5]));
workerLRSR.execute();
}
else if(algo.equals("R+L")){
//eseguo entrambi
File[] folders = {new File(urlFrames+"\finalRSR"),new File(urlFrames+"\finalLRSR")};
//eseguo RSR
folders[0].mkdir();
WorkerRSR workerRSR = new WorkerRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7]);
workerRSR.execute();
//eseguo LRSR
folders[1].mkdir();
WorkerLRSR workerLRSR = new WorkerLRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7],Integer.parseInt(tmp[4]),Integer.parseInt(tmp[5]));
workerLRSR.execute();
}
System.out.println("fine for "+sem.availablePermits());
}
codatof = true;
}
//trying to acquire
try {
sem.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
JOptionPane.showMessageDialog(null,"Coda Eseguita", "Attenzione",JOptionPane.WARNING_MESSAGE);
}
编辑:这是两个工人的尸体。这不是完整的代码,我不包括构建器和其他会使它毫无意义地更长的东西。
两个 worker 之间的主要区别在于,RSR 将调用名为 "MakeRSR" 的 class,而 LRSR 将调用名为 "LRSR.exe"
的 exe 文件
WorkerRSR(完成方法):
@Override
protected void done() {
PanelRSR_LRSR.getProgessbar().setIndeterminate(false);
if (codatof) //codatof will be false
JOptionPane.showMessageDialog(null,"Finito RSR", "Attenzione",JOptionPane.WARNING_MESSAGE);
else{
CreateOption.sem.release();
System.out.println("Semaforo liberato");
}
System.out.println("Algoritmo RSR esguito");
System.out.println("L'output e' stato salvato in: "+ urlFrames+"\finalRSR ");
System.out.println("RSR sem "+CreateOption.sem.availablePermits());
}
如果您的 Worker 类 正在同步处理数据(即在同一线程上),那么可以保证在您退出 for 循环时所有字符串都已处理。如果工作人员 类 正在执行异步操作,最好的解决方案是使用 ExecutorService,您可以使用它来等待并在所有作业完成时报告。事实上,ExecutorService 是一个围绕 Thread.join 的框架,您也可以使用它来等待所有异步操作完成。
-----编辑------
啊,所以你正在使用 SwingWorkers。在这种情况下,您不能改用 Thread.join(),我建议您使用信号量 (docs.oracle.com/javase/8/docs/api/java/util/concurrent/…) 以负计数 (1 - coda.size()), 在主线程中调用 acquire() 并在 SwingWorker 线程中调用 release()
如果我正确理解了您要实现的目标,请使用:
//this will restart the for loop until the stop criteria
//is met
while (true){
//the for loop
for (int i = 0; i<coda.size(); i++){
//...........
}
//stop criteria
if (variable == coda.size()) break ;
}//end of while loop
我知道这个问题之前可能有人问过,但我找不到任何主题,所以我打开这个。
在这段代码中,我有一个字符串 ArrayList (coda) 和一个字符串数组,我用它来拆分 ArrayList 的每个元素。在 for 的每次迭代中,我都会将一个元素提供给 class(WorkerRSR、WorkerLRSR 或两者),而那些 class 将执行不相关的操作。我想要的是在 for 的右大括号生效后执行 do-while。
Do-While 详细信息: 这是确保每个字符串都已被 classes 完全处理所必需的。在每个 运行 之后,每个 class 都会将变量编号增加 1,以便我知道所有元素何时完成。不幸的是,这样的 do-while 会冻结整个程序。
有没有办法在循环中检查变量?我知道我应该使用线程;我也检查了他们,但没有太大帮助..
//Let's pretend I have a fixed number or elements (3)
public static Semaphore sem = new Semaphore(-2,true);
[...]
if (src == execoda){
if (coda.size()==0){
JOptionPane.showMessageDialog(null,"La coda è vuota. Aggiungere elementi alla coda", "Attenzione",JOptionPane.INFORMATION_MESSAGE);
}
else{
System.out.println("inizio for "+sem.availablePermits());
codatof = false;
for (int i = 0; i<coda.size(); i++){
String[] tmp = ((String)coda.get(i)).split("-");
algo = tmp[6];
if(algo.equals("RSR")){
File[] folders = {new File(urlFrames+"\finalRSR"),};
folders[0].mkdir();
//parametri WorkerRSR: String urlImg, int dist, int numI, int spra, String algo (6), String urlFrames (7)
WorkerRSR workerRSR = new WorkerRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7]);
workerRSR.execute();
}
else if(algo.equals("LRSR")){
File[] folders = {new File(urlFrames+"\finalLRSR"),};
folders[0].mkdir();
//parametri WorkerLRSR: String urlImg, int dist, int numI, int spra, String algo, String urlFrames
WorkerLRSR workerLRSR = new WorkerLRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7],Integer.parseInt(tmp[4]),Integer.parseInt(tmp[5]));
workerLRSR.execute();
}
else if(algo.equals("R+L")){
//eseguo entrambi
File[] folders = {new File(urlFrames+"\finalRSR"),new File(urlFrames+"\finalLRSR")};
//eseguo RSR
folders[0].mkdir();
WorkerRSR workerRSR = new WorkerRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7]);
workerRSR.execute();
//eseguo LRSR
folders[1].mkdir();
WorkerLRSR workerLRSR = new WorkerLRSR(tmp[0],Integer.parseInt(tmp[1]),Integer.parseInt(tmp[2]),Integer.parseInt(tmp[3]),tmp[6],tmp[7],Integer.parseInt(tmp[4]),Integer.parseInt(tmp[5]));
workerLRSR.execute();
}
System.out.println("fine for "+sem.availablePermits());
}
codatof = true;
}
//trying to acquire
try {
sem.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
JOptionPane.showMessageDialog(null,"Coda Eseguita", "Attenzione",JOptionPane.WARNING_MESSAGE);
}
编辑:这是两个工人的尸体。这不是完整的代码,我不包括构建器和其他会使它毫无意义地更长的东西。 两个 worker 之间的主要区别在于,RSR 将调用名为 "MakeRSR" 的 class,而 LRSR 将调用名为 "LRSR.exe"
的 exe 文件WorkerRSR(完成方法):
@Override
protected void done() {
PanelRSR_LRSR.getProgessbar().setIndeterminate(false);
if (codatof) //codatof will be false
JOptionPane.showMessageDialog(null,"Finito RSR", "Attenzione",JOptionPane.WARNING_MESSAGE);
else{
CreateOption.sem.release();
System.out.println("Semaforo liberato");
}
System.out.println("Algoritmo RSR esguito");
System.out.println("L'output e' stato salvato in: "+ urlFrames+"\finalRSR ");
System.out.println("RSR sem "+CreateOption.sem.availablePermits());
}
如果您的 Worker 类 正在同步处理数据(即在同一线程上),那么可以保证在您退出 for 循环时所有字符串都已处理。如果工作人员 类 正在执行异步操作,最好的解决方案是使用 ExecutorService,您可以使用它来等待并在所有作业完成时报告。事实上,ExecutorService 是一个围绕 Thread.join 的框架,您也可以使用它来等待所有异步操作完成。
-----编辑------
啊,所以你正在使用 SwingWorkers。在这种情况下,您不能改用 Thread.join(),我建议您使用信号量 (docs.oracle.com/javase/8/docs/api/java/util/concurrent/…) 以负计数 (1 - coda.size()), 在主线程中调用 acquire() 并在 SwingWorker 线程中调用 release()
如果我正确理解了您要实现的目标,请使用:
//this will restart the for loop until the stop criteria
//is met
while (true){
//the for loop
for (int i = 0; i<coda.size(); i++){
//...........
}
//stop criteria
if (variable == coda.size()) break ;
}//end of while loop