简体   繁体   中英

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 . I've got the progressbar setup correctly because I've tested that on the side. 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();
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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