我正在尝试学习如何正确使用多线程,并且由于某种原因,我的代码在一次迭代后通过更新progressbar
来保持冻结。我已正确设置了progressbar
,因为我已对此进行了测试。我以为我的多线程是正确的,但这两个类似乎没有正确的沟通。任何训练有素的人都可以在这里发现我的错误吗?谢谢
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.border.Border;
public class ProgressBar {
static int j = 0;
static int n = 0;
synchronized public static void main(String args[]) {
double percent = .01;
n = Integer.parseInt(JOptionPane.showInputDialog("pick a really big number for no reason"));
//this block is just the progress bar
JFrame f = new JFrame("Progress Bar");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
JProgressBar progressBar = new JProgressBar();
progressBar.setValue(0);
progressBar.setStringPainted(true);
Border border = BorderFactory.createTitledBorder("Reading...");
progressBar.setBorder(border);
content.add(progressBar, BorderLayout.NORTH);
f.setSize(300, 100);
f.setVisible(true);
//this block is just the progress bar
Computation c = new Computation();
c.start();
while(percent <= 1.0){
if( j >= (n*percent) ){
progressBar.setValue((int) (percent*100));
progressBar.repaint();
percent += .01;
}
else{
continue;
}
}
}
public static class Computation extends Thread{
synchronized public void run(){
while( j < n ){
j++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
答案 0 :(得分:0)
您需要同步对共享数据的访问权限。需要使用同一对象完成同步。这是一个解决方案,可能不是最好的,但至少它是有效的。还要注意等待的循环。这是典型的,检查您是否符合继续进行的条件。
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.border.Border;
import java.awt.*;
import java.util.concurrent.locks.Condition;
public class ProgressBar {
static final Object lock = new Object();
static int j = 0;
static int n = 0;
public static void main(String args[]) throws InterruptedException {
double percent = .01;
n = Integer.parseInt(JOptionPane.showInputDialog("pick a really big number for no reason"));
//this block is just the progress bar
JFrame f = new JFrame("Progress Bar");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = f.getContentPane();
JProgressBar progressBar = new JProgressBar();
progressBar.setValue(0);
progressBar.setStringPainted(true);
Border border = BorderFactory.createTitledBorder("Reading...");
progressBar.setBorder(border);
content.add(progressBar, BorderLayout.NORTH);
f.setSize(300, 100);
f.setVisible(true);
//this block is just the progress bar
Computation c = new Computation();
c.start();
while (percent <= 1.0) {
synchronized (lock) {
while (j < n * percent) {
lock.wait();
}
}
progressBar.setValue((int) (percent * 100));
progressBar.repaint();
percent += .01;
}
}
public static class Computation extends Thread {
public void run(){
while(true) {
synchronized (lock) {
if (j >= n) break;
j++;
lock.notify();
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}