2013-07-04 102 views
6

如何啓動兩個線程,其中thread1首先執行,當thread1結束時線程2啓動,而主方法線程可以繼續工作而不鎖定另外兩個線程?我已經嘗試過join(),但它需要從線程中調用,必須等待另一個線程,因爲沒有辦法像thread2.join(thread1)這樣做。 如果我在main()內部調用一個連接,我因此有效地停止了主線程的執行,而不僅僅是thread2的執行。當主線程繼續執行時,執行兩個等待另一個線程的線程

因此,我嘗試使用ExecutorService,但同樣的問題。

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class Test 
{ 
    public static void main(String args[]) throws InterruptedException 
    { 
     System.out.println(Thread.currentThread().getName() + " is Started"); 

     class TestThread extends Thread 
     { 
      String name; 
      public TestThread(String name) 
      { 
       this.name = name; 
      } 

      @Override 
      public void run() 
      { 
       try 
       { 
        System.out.println(this + " is Started"); 
        Thread.sleep(2000); 
        System.out.println(this + " is Completed"); 
       } 
       catch (InterruptedException ex) { ex.printStackTrace(); } 
      } 

      @Override 
      public String toString() { return "Thread " + name; } 
     } 

     ExecutorService executor = Executors.newCachedThreadPool(); 
     executor.execute(new TestThread("1")); 

     boolean finished = executor.awaitTermination(1, TimeUnit.HOURS); 

     if(finished) 
     { 
      //I should execute thread 2 only after thread 1 has finished 
      executor.execute(new TestThread("2")); 
     } 

     //I should arrive here while process 1 and 2 go on with their execution 
     System.out.println("Hello"); 
    } 
} 

#EDIT:爲什麼我需要這樣的:

我需要這個,因爲從數據庫表線程1份的元素到另一個數據庫,線程2具有複製它引用從線程1複製的表,一個鏈接表。 因此,thread2必須僅在thread1完成時纔開始填充鏈接表,否則數據庫會給出完整性錯誤。 現在想象一下,由於複雜的鏈接表,我有幾個不同優先級的線程,你有一個想法。

+7

你爲什麼需要2個線程,如果他們強制執行了一個又一個? – Tala

+0

我在上面添加了「爲什麼我需要這個」。希望它很明確 – dendini

+0

不是真的,沒有。 –

回答

3

第二個線程可以定製這樣(把參數作爲前一個線程):

public static void main(String[] a) { 
    Thread first = new Thread(new Runnable() { 
     @Override 
     public void run() { 

     } 
    }); 

    Thread second = new MyThread(first); 
    first.start(); 
    second.start(); 

    //continue executing 
} 

public static class MyThread extends Thread { 

    private Thread predecessor; 

    public MyThread(Thread predecessor) { 
     this.predecessor = predecessor; 
    } 

    public void run() { 
     if (predecessor != null && predecessor.isAlive()) { 
      try { 
       predecessor.join(); 
      } catch (InterruptedException e) {} 
     } 
     //do your stuff 
    } 
} 
+0

上面的代碼不起作用,只有在第一個完成後,主線才繼續運行。我想第二次鎖定主體直到第一個還沒完成。 – dendini

+0

當然!現在已經修好了 – Tala

3

我敢肯定你有什麼問題,因爲這必須工作,它的工作:

new Thread() { 
    @Override 
    public void run() { 
     TestThread t1= new TestThread("1"); 
     TestThread t2= new TestThread("2"); 
     try { 
      t1.start(); 
      t1.join(); 
      t2.start(); 
      t2.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}.start(); 

的輸出繼電器是:

main is Started 
Hello 
Thread 1 is Started 
Thread 1 is Completed 
Thread 2 is Started 
Thread 2 is Completed 

另一種選擇是延長TestThread對於「線程1」在完成自己的工作後執行「線程2」的工作。一些與此類似:

final TestThread t2= new TestThread("2"); 
TestThread t1= new TestThread("1") { 
    @Override 
    public void run() { 
     super.run(); //finish t1 work 
     t2.start(); // start t2 work 
    } 
}; 
t1.start(); 
+0

t1.join(); - 主線程將等待t1結束。 – Tala

+1

究竟..我想要主線程繼續執行,而不是等待 – dendini

+0

查看更新回答 – darijan

2

您可以使用CountDownLatch:在

創建主線程,將它傳遞給兩個線程,並在線程1中調用倒計時,並等待線程2開始倒計時。

1

爲什麼不只是讓thread1成爲啓動thread2的人呢?

// in main 
new Thread(new Runnable() { 
    @Override public void run() { 
     // do thread1 work 
     new Thread(new Runnable() { 
       @Override public void run() { /* do thread2 work */ } 
     }).start(); 
    } 
}).start(); 

但是,它不完全清楚你爲什麼要這麼做,而不是隻讓thread1做100%的後臺工作。

+0

也許這個顯而易見的解決方案太明顯了 - 另一個海報建議它,並由於某種原因而被降低了投票率。這肯定是最簡單的方式,比明確的信令建議簡單得多。 –

0

愚蠢的問題,但如果線程2應該在線程1完成時執行......爲什麼不從線程1開始呢?

或者,也許只是讓線程1觸發一個事件,主線程可以啓動新的響應。

我發現this的例子,應該爲你工作。

+0

這應該是一個評論,而不是答案。 –

+0

什麼?這是完成OP所需要的完全合理的方式。 –

+0

..儘管這是一個愚蠢的要求。 –

1

您可以使用SingleThreadExecutor運行陸續Java doc

一個任務,所以它會把你的任務一個接一個,他們會按順序執行而不會阻塞主線程

0

您可以相繼運行兩個線程一個通過使用幾種方法:

  1. 通過使用join()方法。例如:

    Thread t1=new Thread(new Runnable() { 
        @Override 
        public void run() { 
         for (int i = 0; i < 4; i++) { 
          System.out.println("A " + i); 
         } 
        } 
    }); 
    Thread t2=new Thread(new Runnable() { 
        @Override 
        public void run() { 
         for (int i = 0; i < 4; i++) { 
          System.out.println("B " + i); 
         } 
        } 
    }); 
    
  2. 通過使用wait()和通知()的方法:離。

`

{ 
public class NotiffyAllExample { 

    int flag = 1; 

    public static void main(String[] args) { 

     NotiffyAllExample notiffyAllExample = new NotiffyAllExample(); 

     A1 a = new A1(notiffyAllExample); 
     B1 b = new B1(notiffyAllExample); 
     C1 c = new C1(notiffyAllExample); 
     a.start(); 
     b.start(); 
    } 
} 

class A1 extends Thread { 

    NotiffyAllExample notiffyAllExample; 

    public A1(net.citigroup.mexico.pg.test.test.NotiffyAllExample notiffyAllExample) { 
     this.notiffyAllExample = notiffyAllExample; 
    } 

    @Override 
    public void run() { 

     try { 
      synchronized (notiffyAllExample) { 

       for (int i = 0; i < 4; i++) { 

        while (notiffyAllExample.flag != 1) { 
         notiffyAllExample.wait(); 
        } 
        System.out.print("A "); 
       } 
       notiffyAllExample.flag = 2; 
       notiffyAllExample.notifyAll(); 
      } 
     } catch (Exception e) { 
      System.out.println("Exception 1 :" + e.getMessage()); 
     } 

    } 
} 

class B1 extends Thread { 

    NotiffyAllExample notiffyAllExample; 

    public B1(NotiffyAllExample notiffyAllExample) { 
     this.notiffyAllExample = notiffyAllExample; 
    } 

    @Override 
    public void run() { 
     try { 
      synchronized (notiffyAllExample) { 

       for (int i = 0; i < 4; i++) { 

        while (notiffyAllExample.flag != 2) { 
         notiffyAllExample.wait(); 
        } 
        System.out.print("B "); 
       } 
       notiffyAllExample.flag = 1; 
       notiffyAllExample.notifyAll(); 

      } 
     } catch (Exception e) { 
      System.out.println("Exception 2 :" + e.getMessage()); 
     } 

    } 
} 
} 

`

相關問題