通过多线程增加JavaFX中ProgressBar的进度

通过多线程增加JavaFX中ProgressBar的进度,java,javafx,download,progress-bar,Java,Javafx,Download,Progress Bar,我正在创建一个JavaFX应用程序,它将通过网络发送多个文件,我希望有一个进度条,显示发送的字节数。我已经有了将要发送的文件的总大小,但是,我不知道如何增加进度条 问题是,我同时发送文件,所以我不能在我的下载类中设置进度,因为这会被另一个威胁覆盖 这就是我的下载类的外观: iStream = socket.getInputStream(); bufferSize = socket.getReceiveBufferSize(); fos = new

我正在创建一个JavaFX应用程序,它将通过网络发送多个文件,我希望有一个进度条,显示发送的字节数。我已经有了将要发送的文件的总大小,但是,我不知道如何增加进度条

问题是,我同时发送文件,所以我不能在我的下载类中设置进度,因为这会被另一个威胁覆盖

这就是我的下载类的外观:

        iStream = socket.getInputStream();
        bufferSize = socket.getReceiveBufferSize();
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        byte[] bytes = new byte[bufferSize];
        int count;
        while ((count = is.read(bytes)) >= 0) {
            bos.write(bytes, 0, count);
        }
        bos.close();
        is.close();
我以以下方式执行该类:

List<Callable<String>> downloadTasks = new ArrayList<>();
Callable<String> download = new Download(new File(path), portnumber);
downloadTasks.add(download);
es.invokeAll(downloadTasks);
List downloadTasks=new ArrayList();
可调用下载=新下载(新文件(路径)、端口号);
下载任务。添加(下载);
es.invokeAll(下载任务);
我有两个类中变量
long totalSize
中的总字节数


你能帮我实现字节进度条吗?谢谢

您只能从单个线程更新进度条:FX应用程序线程。所以线程问题是没有意义的;您只需增加一个表示下载的总字节数的属性,并安排仅从该线程更新它

比如:

public class UploadProgressMonitor {

    private final long totalBytes ;
    private long downloadedBytes ;
    private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper() ;

    public UploadProgressMonitor(long totalBytes) {
         this.totalBytes = totalBytes ;
    }

    private void doIncrement(long bytes) {
        downloadedBytes += bytes ;
        progress.set(1.0 * downloadedBytes / totalBytes);
    }

    public void increment(long bytes) {
        if (Platform.isFxApplicationThread()) {
            doIncrement(bytes);
        } else {
            Platform.runLater(() -> doIncrement(bytes));
        }
    }

    public ReadOnlyDoubleProperty progressProperty() {
        return progress.getReadOnlyProperty() ;
    }

    public final double getProgress() {
        return progressProperty().get();
    }
}
现在,您可以执行以下操作:

long totalBytes = ... ;
UploadProgressMonitor monitor = new UploadProgressMonitor(totalBytes);
progressBar.progressProperty().bind(monitor.progressProperty());
如果您给每个任务一个对
UploadProgressMonitor
的引用,它只需要执行以下操作:

    int count;
    while ((count = is.read(bytes)) >= 0) {
        bos.write(bytes, 0, count);
        monitor.increment(count);
    }

谢谢,它可以工作,但问题是,进度条停止在90%左右。如果我在下载后计算int count的大小,它大约是OS/Files.size()报告的总大小(字节)的90%。你有关于如何解决这个问题的建议吗?我想这与线程有关。如果我只发送一个文件,它将达到100%。如果我发送两个相等的文件,它将达到大约50%。@Peter No。。。要进行调试,您可以检查每次下载的
计数是否等于单个文件的预期总大小。确保正确计算总数,并确保每次发送缓冲区时都在增加监视器(例如,确保没有遗漏最后一个或类似的错误)。这听起来好像你的代码中有个bug。同样,我发布的代码基本上都是单线程的。对不起,我修复了它。它很好用。我犯了一个错误,为每个线程创建了一个新的上传进度监视器。。。。