简体   繁体   English

需要帮助来了解Java中的线程

[英]Need help understanding threads in Java

Ok, I am creating a Java program that is to download mods for the game Minecraft . 好的,我正在创建一个Java程序来下载Minecraft游戏的mod。 I have the following class that does all the downloading and that works fine. 我有以下课程可以完成所有下载工作,并且工作正常。 But I have an issue where the progress bar does not update whilst the mod is downloading (the whole program freezes whilst downloading) 但是我有一个问题,即在下载mod时进度条不更新(下载时整个程序冻结)

After much research, other people seem to have the same issue and it can be resolved by using threads. 经过大量研究,其他人似乎也有相同的问题,可以通过使用线程来解决。

I just need to know if it is possible to do this using my existing code or do I have to completely re-write my this java class? 我只需要知道是否可以使用现有代码来执行此操作,还是必须完全重写此java类?

package com.anarcist.minemodloader;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.swing.JProgressBar;

public class modsDownloader {
    public static Boolean downloadMod(String mod, String saveLoc, JProgressBar progress){
        try {
            URL url = new URL(mod);
            //Set ProgressBar to 0%
            progress.setValue((int)0);
            //Open the Connection to the file
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            //Get filesize
            int filesize = connection.getContentLength();
            //Start reading at byte 0
            float totalDataRead = 0;

            BufferedInputStream in = new BufferedInputStream(connection.getInputStream());
            FileOutputStream fos = new FileOutputStream(saveLoc);
            BufferedOutputStream bout = new BufferedOutputStream(fos, 1024);

            byte[] data = new byte[1024];

            int i=0;
            while((i = in.read(data, 0, 1024)) >= 0){
                totalDataRead = totalDataRead + i;
                bout.write(data,0,i);
                float Percent=(totalDataRead * 100) / filesize;
                progress.setValue((int)Percent);
            }
            bout.close();
            in.close();
        }catch(Exception e){
            javax.swing.JOptionPane.showConfirmDialog((java.awt.Component)
            null,e.getMessage(), "Error",
            javax.swing.JOptionPane.DEFAULT_OPTION);
        }
        return true;
    }
}

Additionally, this function/class is called using the following code: 此外,使用以下代码调用此函数/类:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    Object selectedObj = modsList.getSelectedValue();
    if (selectedObj instanceof modsListItem) {
        try {
            modsListItem selectedItem = (modsListItem) selectedObj;
            System.out.println(selectedItem.getValue());
            String fullName = selectedItem.getValue();
            String fileParts[] = fullName.split("/");
            String fileName = fileParts[fileParts.length - 1];
            String saveLoc = config.getModsFolder(true) + "/" + fileName;
            modsDownloader.downloadMod(selectedItem.getValue(), saveLoc, jProgressBar1);
        } catch (IOException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
} 

This method call's yours and passes the parameters in a separated thread, but the return true statement is executed in the main thread, so, it may return true although your thread has not ended doing his work. 该方法调用是您的,并在单独的线程中传递参数,但是return true语句在主线程中执行,因此,尽管您的线程尚未结束其工作,但它可能返回true。

public static Boolean downloadModThread(String mod, String saveLoc, JProgressBar progress){
    new Thread(
        new Runnable(){
            public void run(){

                downloadMod(mod, saveLoc, progress);
            }
        }
    ).start();
    return true;

}

You can use Swing invokeAndWait() or invokeLater() invokeAndWait method in SwingUtilities concept like a FIFO logic the do a particular job and trigger something after it completes 您可以像FIFO逻辑一样在SwingUtilities概念中使用Swing invokeAndWait()invokeLater() invokeAndWait方法,例如FIFO逻辑,完成特定工作并在完成后触发某些操作

You can use SwingWorker logic to perform a long running task and also update the UI periodically 您可以使用SwingWorker逻辑来执行长时间运行的任务,还可以定期更新UI

Refer How do I use SwingWorker in Java? 请参阅如何在Java中使用SwingWorker?

Refer Stop/cancel SwingWorker thread? 请参阅停止/取消SwingWorker线程?

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

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