2014-10-16 154 views
3

我正在學習Java,但遇到同步問題。我想從許多Java線程打印數字列表,並讓每個線程按順序排列。我在使用synchronized時遇到問題,因爲我不太瞭解。可以幫助理解?Java基本同步線程

我想輸出看到這一點,但有時錯order.i線程想:

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

我破碎的代碼:

public class ManyThreadsAdd { 
    public static int index = 0; 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public synchronized void run() { 
      while (index < 49) { 
       try { 
        Thread.sleep(100); 
        System.out.println(index+"-" +Thread.currentThread()); 
        index = index + 1; 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+1

你必須使用'等待()'和'通知()'這裏。你需要線程之間的某種通信來實現你的輸出。 – TheLostMind 2014-10-16 14:18:39

+0

是的,我嘗試等待並通知,但總是錯誤的例外。也許普通的班級使用wait和notify? – JoeJoeJoeJoe4 2014-10-16 14:39:40

+0

你必須使用共享鎖。請參閱http://stackoverflow.com/q/6017281/217324的接受答案。投票結束,因爲這是同樣的問題。我試着爲你選擇一個好的,但如果這不能解決你的問題,有很多其他問題發佈在這個問題上有答案,谷歌爲「Java多線程甚至奇怪的網站:stackoverflow.com」。 – 2014-10-16 15:11:44

回答

2

這取決於你想要做什麼。

交替打印順序的一種簡單方法是在同一個對象上進行同步,在這種情況下,您可以使用索引或任何其他對象。

public class ManyThreadsAdd { 
    public static AtomicInteger index = new AtomicInteger(0); 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public void run(){ 
      synchronized(index){ 
       while(index.get() < 49){ 
        try { 
         Thread.sleep(100); 
         System.out.println(index.get()+"-" +Thread.currentThread()); 
         index.incrementAndGet(); 
         index.notify(); 
         index.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 
} 
+0

這個我明白最好。容易看到原子增量,然後通知()和等待()。謝謝 – JoeJoeJoeJoe4 2014-10-16 18:16:15

2

首先,多線程本質上是異步的,你不能指定這些線程執行的順序。如果你想要像下面的輸出,使用循環:

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

其次,可以通過在public synchronized void run()加入​​關鍵字一無所獲。這意味着在任何時候,一次只有一個線程可以調用該方法。當你爲每個線程構造新的類時,這是沒有意義的。

第三,如果您確實需要在您的線程之間進行同步,請使用您添加任務的隊列以及您的線程一次讀取的隊列。

+0

你總是打開新的RunnableClass,所以不會有同步。 做單身課。 – 2014-10-16 14:20:11