问题描述
我正在尝试学习如何正确使用多线程,并且由于某种原因,通过更新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();
}
}
}
}
}
1楼
您需要同步对共享数据的访问。 同步需要使用相同的对象来完成。 这是一个解决方案,也许不是最好的,但至少可以奏效。 还要注意等待的循环。 这是典型的,以检查您是否满足条件进行。
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();
}
}
}
}
}