2012-08-22 58 views
0

之前,我一直认为我的管理界面和呼叫项目对象以进口物品的方法在我的DB一个JFrame子类:等待,直到线程执行结束执行下一个方法

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 

    } 


} 

执行导入操作如何修改代码来执行table.refresh()只有Item.importImtes(progressBar)结束它的运行后?谢谢!

+0

查看我的更新回答 – Eugene

回答

2

如果你想一个线程等待另一个,你可以随时使用CountDownLatch也。使用一个也意味着你不必等到一些线程完成。如果你让你的问题对我们更好理解,我们可以帮助你了解更多细节。

你需要共享的CountDownLatch例如线程之间:

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 
    } 


} 
+1

我试图更好地解释它。几分钟后检查第一篇文章。谢谢! – Luca

+0

使用此代码,refries()在导入终止后正确执行,但最大的问题是这会冻结UI,并且我无法更新progressBar状态。任何建议?再次感谢!! – Luca

+0

@Luca然后你需要在一个新的Thread中执行table.refresh(),从而允许主线程进一步执行。 – Eugene

3

在线程上使用.join()方法。

+0

问题是我不能阻止当前线程,因为在当前线程中,我在其他线程执行期间更新UI – Luca

0

<线程> .join()方法会阻塞当前线程,直到<线程>已完成。

0

这是你应该如何使用它:

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"); 
    } 
} 

OUTPUT:

Main Thread Start 
Progress Bar - start 
Progress Bar - end 
Main Thread End 
+0

此代码中的问题是我无法锁定当前线程与.join()方法,因为在那种情况下,我不能更新我的应用程序的用户界面。我可能需要第三个线程?谢谢! – Luca

+0

@Luca似乎需要3个线程1)执行TestGUI方法2)一个导入项目3)另一个线程将执行table.refresh()。你想要3等2,但1会继续它的正常工作? – Eugene

+0

@Luca基本上你想同时启动线程1和线程2。然后,线程1应该只在线程2也终止时终止。对 ?如果是,那么......运行线程1启动,线程2启动,使线程2获得锁定并使线程1等待它。当线程2完成其工作时,释放锁并完成两个线程的处理。如何使用信号量看到我的帖子:http://stackoverflow.com/questions/12052232/thread-syncronization/12052750#12052750 – Vivek

0

你可以做的是底了移动table.refresh();码子线程代码并使用SwingUtilities.InvokeLater将其转发到GUI线程事件队列:

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

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