2015-05-19 128 views
1

我想知道如何使這些線程一個接一個地工作,以及如何使第一個線程在第二個線程之後始終運行。我創建了一個信號量,但我不確定如何使用它。使用信號燈

public class A extends Thread { 
    private int i; 
    public A(int x) { 
     i = x; 
    }@ 
    Override 
    public void run() { 
     System.out.println(i); 
    } 
} 

/**主**/

A c1 = new A(5); 
A c2 = new A(6); 
Semaphore s = new Semaphore(1, true); 
c1.start(); 
c2.start(); 

new Thread(new Runnable() { 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) {} 
      System.out.println("+"); 
     } 
    } 
}).start(); 

new Thread(new Runnable() { 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      try { 
       Thread.sleep(70); 
      } catch (InterruptedException e) {} 
      System.out.println("*"); 
     } 

    } 
}).start(); 
+2

一個其他=連續之後。爲什麼你想要多個線程? –

+0

爲了行使我在控制線程 – Csi

+2

這沒有任何意義。開始第一個線程。 '加入'就可以了。然後'開始'第二個線程。然後'加入'。這裏沒有理由使用「信號量」。 –

回答

0
  • 我想知道怎樣才能讓這些線程的工作一個接一個,和
  • 如何讓第一個總是在第二個之後運行。我創建了一個信號量,但我不確定如何使用它。

如果你想線程調用線程C2之前完成你可以在你的情況下使用join()。像這樣(的主題被稱爲在main線程):

c1.start(); // Start thread `c1` first 
c1.join(); // `main` now waits for `c1` to finish 
c2.start(); // Start thread `c2` next 
c2.join(); // `main` now waits for `c2` to finish 

這應該回答你的問題。

我關於信號量的一點點。

一般來說,您不能使用信號量來控制線程的執行順序。信號量是一個或多個資源的鎖。希望訪問資源的線程彼此競爭,您無法控制信號量接下來將授予訪問權限的用戶。

我知道其他答案中的「詭計」。我沒有測試它,它可能工作,但我不認爲這是做到這一點的正確方法。

這裏是沒有sempahore工作的例子:

import java.util.concurrent.Semaphore; 

class A extends Thread { 

    private int i; 
    public A(int x) { 
     i = x; 
    } 

    public void run() { 
     System.out.println(i); 
    } 

    public static void main(String[] args) throws Exception { 
     A thread1 = new A(5); 
     A thread2 = new A(6); 
     thread1.start(); 
     thread1.join(); 
     thread2.start(); 
     thread2.join(); 
    } 
} 

如果你想使用一個信號量(雖然我不明白爲什麼),那麼例如可以是這樣的:

import java.util.concurrent.Semaphore; 

class A extends Thread { 

     private int i; 
     final static Semaphore semaphore = new Semaphore(1, true); 

     public A(int x) { 
      i = x; 
     } 

     public void run() { 
      try { 

       /*thread stops here until it gets permit to go on*/ 
       semaphore.acquire(); 
       System.out.println(i); 
      /*exception must be caught or thrown*/ 
      } catch (InterruptedException e) { } 

      //CRITICAL SECTION 

      semaphore.release(); 

     } 

    public static void main(String[] args) throws Exception { 
     A thread1 = new A(5); 
     A thread2 = new A(6); 
     thread1.start(); 
     thread1.join(); 
     thread2.start(); 
     thread2.join(); 
    } 
} 
+0

Sry,我不在家。在我的例子中,有可以用join()組織的c1和c2線程;如你所說。現在我懂了。但是主體中還有兩個「新線程」執行自己。這裏需要信號量,因爲沒有使用join()方法的實例名稱。用你的例子,我也設法控制它們,謝謝你,先生。 – Csi

+0

在這種情況下,請使用具有公平選項的二進制信號量。如果它幫助你解決問題,請隨時注意並接受答案。 – Elyasin

0

可以在信號量許可證模型來表示: 「允許運行」。

由於您希望允許第一個線程自動運行,因此第一個線程不能使用acquire,因爲它將與第二個線程競爭許可。所以第一個線程開始,假設它有許可證。當第一個線程完成時,它是release-是許可證。第二個線程需要acquire許可才能開始工作。

首先創建零個許可

final Semaphore s = new Semaphore(0, true); 

(因爲一個許可證已經被隱含的第一個線程擁有)在第一線中的最後一行應改爲旗語:

s.release(); 

(注它允許在沒有獲得的情況下發布 - 信號量只是計數,它不記錄哪個擁有哪個許可)

而第二個線程中的第一行應改爲:

s.acquireUninterruptibly(); 

(或只是acquire()但隨後你需要趕上InterruptedException

0

儘管你的問題可以通過 可以強制完成一個線程的「連接」功能來解決,但在開始下一個asi之前(如圖所示) Elyasian的例子,但仍然必須補充說明你在右邊跟蹤 就信號量航線而言。

信號量s =新的信號量(1,true);

在本聲明中,將第二個參數設置爲「true」被稱爲公平設置。

這確保(FIFO - 先進先出)在我們的場景換句話說,「先到先得」 ......

即調用獲得第一將獲得許可,將完成 線程其任務第一,然後第二個線程將能夠執行 它的執行。

所以你原來的問題.....即

我想知道我怎樣才能使這些線程的工作一個接一個,以及如何使第一個總是第二個

後運行

的措詞,

我想知道我怎樣才能確保調用線程獲得 首先在信號到達第一始終運行....