当前位置: 首页 > 面试题库 >

在主线程中完成工作之前,线程中的进度条不会更新其UI

公西宏峻
2023-03-14
问题内容

我正在将一个大文件切成块,并想显示进度。当我单击startCut Button时,这是要执行的代码:

FileInputStream in = new FileInputStream(sourceFile);
int blockSize = (int)(getSelectedBlockSize() * 1024);
int totalBlock = Integer.parseInt(txtNumberOfBlock.getText());
byte[] buffer = new byte[blockSize];
int readBytes = in.read(buffer);
int fileIndex = 1;

class PBThread extends Thread
{
    @Override
    public void run()
    {
        while(true)
        {
            pbCompleteness.setValue(value);
            //value++; //place A
            System.out.println(value);
            if (value >= 100)
                break;
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
        }
    }
}
value = 0;
PBThread pbThread = new PBThread();
pbThread.start();
while(readBytes != -1)
{
    File file = new File(targetFilePath + fileIndex);
    FileOutputStream out = new FileOutputStream(file);
    out.write(buffer, 0, readBytes);
    out.close();
    value = (int)(fileIndex / (double)totalBlock * 100);// place B
    readBytes = in.read(buffer);
    fileIndex++;
}

我在位置B的运行方法外部更改了进度栏的值,问题是grogressbar仅显示两种状态:0%和100%。但是,如果我删除了位置B的代码,并在位置A的run方法内更改了progressbar的值,问题将消失。我知道也许SwingWorker可以很容易地修复它,但是我确实想知道为什么会发生这种情况,尽管我更改了run方法的值,但是当我在run方法中打印出来时,它确实发生了变化。在运行方法之外更改值时如何解决该问题?


问题答案:

问题的症结在于您正在更新组件pbCompletenessEvent Dispatch Thread之外的其他线程上
。您可以SwingUtilities.invokeLater在您的run()方法中使用来补救此问题;例如

AtomicInteger value = new AtomicInteger(0);
while (true) {
  SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      pbCompleteness.setValue(value.get());
    }
  });

  // Do some work and update value.
}

JProgressBar当您的工作线程继续运行时,这将导致在事件调度线程上更新(并重新绘制)。请注意,为了value在“内部”匿名Runnable实例中进行引用,我将其更改为AtomicInteger。这也是理想的,因为它使线程安全。



 类似资料:
  • 我试图理解Python线程的“守护进程”标志。这我知道 线程可以标记为“守护线程”。此标志的意义在于,当只剩下守护进程线程时,整个Python程序将退出。初始值从创建线程继承。 但在我的例子中,python程序在守护进程线程离开并且线程没有完成其工作之前退出。 主程序 第一个线程只写5000个第一个整数,而第二个线程不写任何数字

  • 问题内容: 主线程将在子线程完成执行之前退出? 我读了两篇文章 http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread- management.html 在以上文章的“线程终止”段中,它用红色表示“如果父线程终止,则其所有子线程也终止。” http://www.roseindia.net/java/thread/overview-

  • 这是我正在研究的完全未来的例子 首先我从SupplySync调用compose方法,在这里我执行方法composeMethod,有三毫秒的延迟,然后它将创建一个文件并返回一个字符串作为结果。完成后,我调用Run方法,它只打印一个方法,然后有一个非阻塞方法从主线程运行。 我在这里面临的问题是,主线程执行完nonblockingmethod()并在3毫秒延迟之前退出进程,而随后的composeMeth

  • 在下面的Haskell代码中,如何强制主线程等待其所有子线程完成。 我无法使用forkFinal,因为在“终止程序”一节中给出了这个链接:(http://hackage.haskell.org/package/base-4.7.0.2/docs/Control-Concurrent.html)。 当使用TMVar时,我得到了想要的结果。但是我想用TVar做这件事。请帮忙。

  • 问题内容: 我正在编写一个具有5个线程的应用程序,这些线程可以同时从Web获取一些信息,并在缓冲区类中填充5个不同的字段。 当所有线程完成其工作时,我需要验证缓冲区数据并将其存储在数据库中。 我该怎么做(当所有线程完成工作时收到警报)? 问题答案: 我采用的方法是使用管理线程池。

  • 问题内容: 我对android完全陌生,只想知道它是否是在主线程外更新UI的任何可行且可行的方法。仅从我的代码中,我就在下面列出了这些代码;根本不可能。但是, 我只想使用另一个线程来更新UI 。请事先帮助我! 问题答案: 使用activity.runOnUiThread