简体   繁体   English

多线程冻结

[英]Multi-Threading Freezing up

I'm trying to learn how to properly use multi-threading and for some reason my code keeps freezing after one iteration through updating my progressbar . 我正在尝试学习如何正确使用多线程,并且由于某种原因,通过更新progressbar我的代码在一次迭代后仍保持冻结。 I've got the progressbar setup correctly because I've tested that on the side. 我已经正确设置了progressbar ,因为我已经在侧面对其进行了测试。 I thought I had my multi-threading correct but the two classes dont seem to be communicating right. 我以为我的多线程正确,但是两个类似乎通信不正确。 Can anyone with a trained eye spot my error here? 训练有素的人可以在这里发现我的错误吗? Thank you 谢谢

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();
                }
            }
        }
    }
}

You need to synchronize the access to the shared data. 您需要同步对共享数据的访问。 The synchronization need to be done using the same object. 同步需要使用相同的对象来完成。 Here is one solution, maybe not the best but at least it works. 这是一个解决方案,也许不是最好的,但至少可以奏效。 Also note the loop surrounding the wait. 还要注意等待的循环。 This is typical, to check whether you have met the condition to carry on. 这是典型的,以检查您是否满足条件进行。

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();
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM