多线程冻结

时间:2015-07-26 05:37:53

标签: java

我正在尝试学习如何正确使用多线程,并且由于某种原因,我的代码在一次迭代后通过更新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 个答案:

答案 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();
                }
            }
        }
    }
}
相关问题