Java Thread.join冻结进度条

Java Thread.join冻结进度条,java,multithreading,swing,Java,Multithreading,Swing,我有一个代码,它使用一个线程来运行多个进度条 Thread thread1 = new Thread(progressbar1); thread1.start(); thread2.start() 等等。等我 thread1.join(); thread2.join(); thread3.join(); 但这会冻结所有三个进度条动画,并仅在所有线程完成时显示完成。 如何解决这个问题? 谢谢。在上执行任何阻塞操作都会导致GUI无响应并停止重新绘制。这就是为什么长时间运行的操作应该在后台线

我有一个代码,它使用一个线程来运行多个进度条

Thread thread1 = new Thread(progressbar1);
thread1.start(); 
thread2.start()
等等。等我

thread1.join(); 
thread2.join(); 
thread3.join();
但这会冻结所有三个进度条动画,并仅在所有线程完成时显示完成。 如何解决这个问题?
谢谢。

在上执行任何阻塞操作都会导致GUI无响应并停止重新绘制。这就是为什么长时间运行的操作应该在后台线程中完成

似乎你知道你需要在后台线程中做一些事情,但仍然想阻止EDT。你不应该那样做。相反,您需要一个回调——一些在后台线程完成运行后将运行的代码


Java 6+中已经提供了一种回调机制。实现一个worker,将
join()
s(和
start()
s)放在
doInBackground()
方法中。然后,您想在之后执行的任何Swing操作都可以进入
done()

中,在上执行任何阻塞操作都会导致GUI无响应并停止重新绘制。这就是为什么长时间运行的操作应该在后台线程中完成

似乎你知道你需要在后台线程中做一些事情,但仍然想阻止EDT。你不应该那样做。相反,您需要一个回调——一些在后台线程完成运行后将运行的代码


Java 6+中已经提供了一种回调机制。实现一个worker,将
join()
s(和
start()
s)放在
doInBackground()
方法中。然后,您想在之后执行的任何Swing操作都可以进入
done()。你不应该那样做。选项:

  • 另一个线程只在前三个线程上调用
    join
    。在创建另一个资源方面是浪费的,但相当简单
  • 使用计数器-确保使用类似于
    AtomicInteger
    的方法来确保不会遇到内存模型和竞争条件问题。从3开始计数器,当最后一个线程完成其工作时,在每个线程结束时将计数器减量(即减量将计数器设置为0),使其回调到UI中
(第二颗子弹可能是你已经在做的事情……很难说清楚,因为只描述了“我用了一个计数器。”)


虽然我完全了解在事件驱动的世界中,应用程序的控制流变得更加困难,但这就是Swing的工作方式(也是大多数其他UI框架的工作方式)。您无法阻止UI线程。(这也是为什么C#5在语言层面上让一切变得更容易的原因…

您正在阻止UI线程。你不应该那样做。选项:

  • 另一个线程只在前三个线程上调用
    join
    。在创建另一个资源方面是浪费的,但相当简单
  • 使用计数器-确保使用类似于
    AtomicInteger
    的方法来确保不会遇到内存模型和竞争条件问题。从3开始计数器,当最后一个线程完成其工作时,在每个线程结束时将计数器减量(即减量将计数器设置为0),使其回调到UI中
(第二颗子弹可能是你已经在做的事情……很难说清楚,因为只描述了“我用了一个计数器。”)


虽然我完全了解在事件驱动的世界中,应用程序的控制流变得更加困难,但这就是Swing的工作方式(也是大多数其他UI框架的工作方式)。您无法阻止UI线程。(这也是为什么C#5让语言层面的学习变得更容易的原因…

你能解释一下你的意思吗?我不知道你所说的阻止UI线程是什么意思。我刚开始学习线程。UI线程(或EDT)是负责处理UI事件(如鼠标单击)和重新绘制屏幕的线程。阻止UI线程仅仅意味着让它做一些需要很长时间才能完成的事情。例如,
join()。。。这可能需要相对较长的时间。阻塞的危害在于在此期间没有处理其他UI事件;i、 e.用户界面变得无响应。(长时间的长度是主观的,但你看到它就会知道。)你能解释一下你的意思吗?我不知道你所说的阻止UI线程是什么意思。我刚开始学习线程。UI线程(或EDT)是负责处理UI事件(如鼠标单击)和重新绘制屏幕的线程。阻止UI线程仅仅意味着让它做一些需要很长时间才能完成的事情。例如,
join()。。。这可能需要相对较长的时间。阻塞的危害在于在此期间没有处理其他UI事件;i、 e.用户界面变得无响应。(长时间的长度是主观的,但你看到它时就会知道。)我使用了一个计数器来跟踪完成了多少线程。当所有线程都完成时,我将doSomething()。但是我想要thread1.start()之后的下一行;thread2.start()doSomething()。但是progressbar都冻结了。@Lewsterin:您需要使用
SwingUtilities.invokeLater
从最后完成的线程调用
doSomething
。基本上你不能在UI线程中做任何长时间运行的事情。我使用了一个计数器来跟踪完成了多少线程。当所有线程都完成时,我将doSomething()。但是我想要thread1.start()之后的下一行;thread2.start()doSomething()。但是progressbar都冻结了。@Lewsterin:您需要使用
SwingUtilities.invokeLater
从最后完成的线程调用
doSo