Java 在执行下一个方法之前,请等待线程执行结束

Java 在执行下一个方法之前,请等待线程执行结束,java,multithreading,Java,Multithreading,我有一个JFrame子类,它管理我的UI并调用Item对象的方法来导入数据库中的项: public TestGUI() throws IOException { initComponents(); Item.importItems(progressBar); // static method that execute a new thread to import item witouth freeze my UI (I update a progressBar in it)

我有一个JFrame子类,它管理我的UI并调用Item对象的方法来导入数据库中的项:

public TestGUI() throws IOException
{

    initComponents();

    Item.importItems(progressBar); // static method that execute a new thread to import item witouth freeze my UI (I update a progressBar in it)

    table.refresh(); //Metodh that I need to execute only after "importItems()" methods is completed

}
Item对象实现Runnable以在新线程中执行导入操作

public Item implements Runnable
{

    private JProgressBar progressBar;

    public void importItems (JProgressBar progressBar) throws IOException //Metodo per importare articoli da un file esterno. Usa i Thread.
    {

        this.progressBar = progressBar;

        Thread importThread = new Thread (new RefreshTable(),"Importer Thread");

        importThread.start();

    }

    void run ()
    {

        // I execute here all the DB operation that i need. I also update the progress bar             here

    }


}

如何修改该代码以仅在
项.importItems(progressBar)
结束执行后执行
表.refresh()
?谢谢

对线程使用.join()方法。

.join()方法将阻止当前线程,直到线程完成。

以下是您应该如何使用它:

class ProgressBar extends Thread{
    public void run(){
        System.out.println("Progress Bar - start");
        try {
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException e) {}
        System.out.println("Progress Bar - end");
    }
}
public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Main Thread Start");
        Thread t1 = new Thread(new ProgressBar());
        t1.start();
        t1.join();
        System.out.println("Main Thread End");
    }
}
输出:

Main Thread Start
Progress Bar - start
Progress Bar - end
Main Thread End
如果您使用
Swing


它们包含辅助线程API

如果您希望一个线程等待另一个线程,您也可以始终使用倒计时闩锁。使用一个线程还意味着不必等到某些线程完全完成。如果您能让我们更好地理解您的问题,我们可以提供更多细节

例如,您需要在线程之间共享倒计时闩锁:

public TestGUI() throws IOException{
      initComponents();
      private final CountDownLatch latch = new CountDownLatch(1);
      Item.importItems(progressBar, latch); // static method that execute a new thread to import item witouth freeze my UI (I update a progressBar in it)
      latch.await();
      table.refresh(); //Metodh that I need to execute only after "importItems()" methods is completed
}
另一方面:

public Item implements Runnable {
    private JProgressBar progressBar;
    public void importItems (JProgressBar progressBar, CountDownLatch latch) throws IOException { //Metodo per importare articoli da un file esterno. Usa i Thread.

        this.progressBar = progressBar;

        Thread importThread = new Thread (new RefreshTable(),"Importer Thread");

        importThread.start();

    }

    void run () {

        // I execute here all the DB operation that i need. I also update the progress bar here
        //After everything finishes:
        latch.countDown(); // you want this to be executed in a finally block of the try catch
    }


}

您可以做的是移动
表.refresh()子线程代码末尾的代码,并使用
SwingUtilities.InvokeLater
将其转发到GUI线程事件队列:

 public void run() {
      //...
      SwingUtilities.InvokeLater(
            new Runnable() {
                 public void run() {
                     table.refresh();
                 }
            });         
 }

这样,您就可以在GUI线程上执行它,但只有在子线程完成其工作时才执行。

问题是我无法阻止当前线程,因为在该线程中,我在其他线程执行期间更新了UI。此代码中的问题是我无法使用.join()锁定当前线程方法,因为在这种情况下,我无法更新应用程序中的UI。我可能需要第三根线?谢谢@Luca似乎需要3个线程1)执行TestGUI方法2)一个导入项目3)另一个执行table.refresh()的线程。您希望3等待2,但1将继续正常工作?@Luca基本上您希望同时启动线程1和线程2。那么线程1应该只在线程2也终止时终止。正确的?如果是,那么。。。运行线程1启动,线程2启动,使线程2获得一个锁,并使线程1等待它。当线程2完成其工作时,释放锁并完成两个线程的处理。如何使用信号量见我的帖子:我认为Eugene和Vivek解决方案都可以解决我的问题。我只需要选择最好的方法。乍一看,我认为Eugene解决方案可能更容易实现implement@Luca事实上,我还没有提出任何解决方案:)我试图更好地解释它。几分钟后查看第一篇文章。谢谢使用这段代码,
refries()
在导入终止后正确执行,但最大的问题是这会冻结UI,我无法更新progressBar状态。有什么建议吗?再次感谢@Luca然后需要在一个新线程中执行table.refresh(),允许主线程进一步执行。我已经想到了这个解决方案,但我需要将表传递给新线程,这正是我试图避免的。thanks@Luca当前位置我看你已经接受了答案。你最终是如何解决这个问题的?