我已经用Java编写了一个简单的应用程序,可以从提供的html链接列表中下载特定的图像。一切工作正常,直到我添加了必须从HTML链接列表中下载而不是从其中下载的功能。我必须实现wait()和notify()方法,这迫使我稍微改变了方法。现在,下载工作正常,但是在下载过程中GUI不会更新。
我使第一个线程从HTML.java等待,并在DownloadImages.java结束时通知它。为此,我不得不将buttonPressed类作为对象而不是线程来调用,这就是为什么我认为我的GUI不会更新的原因。
有没有一种方法可以简化或提高我的代码的线程使用效率?提前致谢。
这是我的代码的骨架:

/*Test.java*/
package my;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Test extends javax.swing.JFrame {

    public static buttonPressed bp;
    public static boolean alldone;

    /** Creates new form Test */
    public Test() {
        initComponents();
    }

    public static class buttonPressed implements Runnable {

        Thread t1, t2;

        buttonPressed() {
            t1 = new Thread(this, "downloadAction");
            t1.start();
        }

        public void suspendThread() {
            System.out.println("suspended");
            alldone = false;
        }

        public synchronized void resumeThread() {
            System.out.println("resumed");
            alldone = true;
            notify();
        }

        public void run() {
            String[] len = new String[]{/*list of urls*/};

            for (int i = 0; i < len.length; i++) {
                System.out.println("going times: " + i);

                t2 = new Thread(new HTML(), "HTMLthread");
                t2.start();

                synchronized (this) {
                    while (!alldone) {
                        try {
                            wait();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    }

    private void downloadActionPerformed(java.awt.event.ActionEvent evt) {
        bp = new buttonPressed();
        try {
            bp.t1.join();
        } catch (InterruptedException e) {
            System.out.println("Main Thread: interrupted");
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Test().setVisible(true);
            }
        });
    }

    private javax.swing.JButton download;
    public static javax.swing.JProgressBar progress;
}



/*HTML.java*/
package my;

import java.util.ArrayList;

class HTML implements Runnable {
    private Thread t3;

    public HTML() {
        Test.bp.suspendThread();
    }

    public void run() {
        downloadHTML();
        ArrayList xyz = parseHTML();
        t3 = new Thread(new DownloadImages(xyz), "DownDecrypt");
        t3.start();
    }

    private void downloadHTML() {
        // Downloads the HTML file
    }

    private ArrayList parseHTML() {
        // Parses the HTML file and gets links to images
        return new ArrayList();
    }
}



/*DownloadImages.java*/
package my;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

class DownloadImages implements Runnable {

    static int current = 0, previous = 0;
    static boolean speedFlag;
    ArrayList<String> links = new ArrayList<String>();
    private Thread t4;

    public DownloadImages(ArrayList param1) {
        this.links = param1;
        speedFlag = true;
    }

    public void run() {
        t4 = new Thread(new getSpeed(), "getSpeed");
        t4.start();
        download(links);
    }

    private void download(ArrayList<String> param1) {
        String[] imgurl = new String[param1.size()];
        URLConnection conn = null;
        InputStream is = null;
        ByteArrayOutputStream bais = null;
        int prog;

        for (int i = 0; i < param1.size(); i++) {
            current = 0;
            imgurl[i] = param1.get(i);
            try {
                conn = new URL(imgurl[i]).openConnection();
                int fsize = conn.getContentLength();
                is = new BufferedInputStream(conn.getInputStream());
                bais = new ByteArrayOutputStream();

                byte[] byteChunk = new byte[1024];
                int n;
                while ((n = is.read(byteChunk)) > 0) {
                    bais.write(byteChunk, 0, n);
                    current = current + 1024;
                    prog = (int) (current * 100.0 / fsize);
                    Test.progress.setValue(prog);
                }
            } catch (MalformedURLException ex) {
                Logger.getLogger(DownloadImages.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException ex) {
                        Logger.getLogger(DownloadImages.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }

            byte[] imgBytes = bais.toByteArray();

            try {
                FileOutputStream fos = new FileOutputStream(i + ".jpg");
                fos.write(imgBytes);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException ex) {
                System.out.println("FileNotFoundException : " + ex);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        speedFlag = false;
        // Resume the thread to start downloading the next link
        Test.bp.resumeThread();
    }

    private static class getSpeed implements Runnable {

        int kbytesPerSecond;
        private final int fireTime;

        public getSpeed() {
            fireTime = 1000;
        }

        public void run() {
            while (speedFlag) {
                try {
                    Thread.sleep(fireTime);
                } catch (InterruptedException ex) {
                    Logger.getLogger(getSpeed.class.getName()).log(Level.SEVERE, null, ex);
                }

                kbytesPerSecond = (((current - previous) / 1024) / (fireTime / 1000));
                System.out.println(kbytesPerSecond);

                previous = current;
            }
        }
    }
}

最佳答案

就GUI而言,您需要阅读有关Swing concurrency的信息。简而言之,使用SwingWorker

请注意,您使用的是旧的AWT内容(java.awt.EventQueue)。

关于java - 在Java中提高线程使用效率,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4608480/

10-09 07:10
查看更多