2012-09-12 74 views
0

可能重複:
Trying to loop 3 threads in a specific order everytime哪有兩個線程訪問同一個對象之一兩種方法陸續在Java

我想從兩個訪問同一個對象的兩種不同的方法線索一個接一個。這裏是我的代碼,

public class ThreadCoordination 
{ 
private Thread threadSayHello; 
private Thread threadSayWorld; 
private boolean threadSayWorldStarted = false; 

public ThreadCoordination() 
{ 
    createThreads(); 
} 

private void createThreads() 
{ 
    threadSayWorld = new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       // while (true) 
       { 
        sayWorld(); 
       } 
      } 
      catch (InterruptedException ex) 
      {} 
     } 
    }); 

    threadSayHello = new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       // while (true) 
       { 
        sayHello(); 

        if (!threadSayWorldStarted) 
        { 
         threadSayWorldStarted = true; 
         threadSayWorld.start(); 
        } 
       } 
      } 
      catch (InterruptedException ex) 
      {} 
     } 
    }); 

    threadSayHello.start(); 
} 

private synchronized void sayHello() throws InterruptedException 
{ 
    System.out.print("Hello "); 
} 

private synchronized void sayWorld() throws InterruptedException 
{ 
    System.out.println("World!"); 
} 

public static void main(String[] args) 
{ 
    new ThreadCoordination(); 
} 
} 

如果我取消呼叫,而(真),那麼我會期待這樣的輸出,

Hello World! 
Hello World! 
Hello World! 
Hello World! 
... 

請指導我我該怎麼做。 拉賈。

我不知道我是否可以編輯封閉的帖子。據我所知,我只想發佈解決方案。

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.ReentrantLock; 

public class SequenceAccess 
{ 
private ReentrantLock myLock; 
private Condition ensureSequence; 
private int sequenceNo = 1; 

public SequenceAccess() 
{ 
    myLock = new ReentrantLock(); 
    ensureSequence = myLock.newCondition(); 

    startThreads(); 
} 

private void startThreads() 
{ 
    new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       while (true) 
        method1(); 
      } 
      catch (InterruptedException ex) 
      {} 
     } 
    }).start(); 

    new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       while (true) 
        method2(); 
      } 
      catch (InterruptedException ex) 
      {} 
     } 
    }).start(); 

    new Thread(new Runnable() 
    { 
     public void run() 
     { 
      try 
      { 
       while (true) 
        method3(); 
      } 
      catch (InterruptedException ex) 
      {} 
     } 
    }).start(); 
} 

private void method1() throws InterruptedException 
{ 
    myLock.lock(); 
    try 
    { 
     while (sequenceNo != 1) 
      ensureSequence.await(); 

     sequenceNo = 2; 
     System.out.println("Method 1"); 
     ensureSequence.signalAll(); 
    } 
    finally 
    { 
     myLock.unlock(); 
    } 
} 

private void method2() throws InterruptedException 
{ 
    myLock.lock(); 
    try 
    { 
     while (sequenceNo != 2) 
      ensureSequence.await(); 

     sequenceNo = 3; 
     System.out.println("Method 2"); 
     ensureSequence.signalAll(); 
    } 
    finally 
    { 
     myLock.unlock(); 
    } 
} 

private void method3() throws InterruptedException 
{ 
    myLock.lock(); 
    try 
    { 
     while (sequenceNo != 3) 
      ensureSequence.await(); 

     sequenceNo = 1; 
     System.out.println("Method 3"); 
     ensureSequence.signalAll(); 
    } 
    finally 
    { 
     myLock.unlock(); 
    } 
} 

public static void main(String[] args) 
{ 
    new SequenceAccess(); 
} 
} 
+0

鎖定對象可以幫助http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html – RNJ

+4

燦你編輯你的帖子來解釋_why_你想要做什麼?線程的整個點是異步並行操作。 – Gray

+3

恕我直言,沒有好的/優雅/有效的方式來做到這一點,因爲它是一個壞主意,使用多個線程來執行一個任務,將更簡單和有效地使用一個線程完成的任務。我可以想出很多可怕的方法來用多線程來做到這一點。;) –

回答

1

的JVM 並不保證線程執行的順序

事實上JVM規範,可以完全由運行Hello線程,直到它結束,然後運行世界線程,直到它終止(與您的程序爲滿足書面)

您需要引入某種令牌才能在兩個線程之間共享,然後讓該令牌來回穿梭。

令牌可以像布爾一樣簡單,如果已輸出hello,則爲true;如果已輸出world,則爲false。

然後,每個線程必須旋轉(或等待條件 - 條件更好的性能),直到布爾值符合其預期狀態。

我建議讓你的手放在最優秀的「Java併發實踐」一書

0

該任務確實有點奇怪,因爲這本質上是一個單線程任務。雖然,我知道應用程序可能會變得非常複雜,並且需要很多奇怪的東西,並且還有多個線程。

您可以創建兩個任意類型的私人對象,例如,將其用作「事件」。每個線程的循環應該爲wait()爲其中一個事件對象,然後執行其任務(打印字符串),然後notify()另一個事件對象,然後再次重複循環和wait()。另一個線程應該執行相同的操作,但事件對象已交換。

啓動兩個線程然後notify()第一個事件對象。行動開始!

相關問題