2014-02-22 69 views
0

我想同時運行兩個不同運行方法的線程。可能嗎?我在下面有簡單的代碼,但它們不兼容。我只想每5秒運行第一個線程,並且總是運行第二個線程。兩個線程不同運行方法並行工作

public static int x = 0; 

public static void main(String[] args) throws InterruptedException{ 

    Runnable r1 = new Runnable() { 
     public void run() { 
      x = x + 1; 
      System.out.println("increment x"); 
     } 
    }; 

    Runnable r2 = new Runnable() { 
     public void run() { 
      System.out.println("x is "+x); 
     } 
    }; 

    while(true){ 
     Thread t1 = new Thread(r1); 
     Thread t2 = new Thread(r2); 
     t1.start(); 
     t2.start(); 
     t1.sleep(5000); 
    } 
} 
+0

a)您不應該無限循環地開始運行已經線程。 b)您不會同步對x的訪問。 c)併發控制檯輸出會導致問題。 – deviantfan

+0

3)Thread.sleep()是靜態的,可以讓* current *線程,而不是被引用線程sleep(與靜態方法一樣,沒有這種東西) –

回答

-1
public class Test { 
public static int x = 0; 

public static void main(String[] args) throws InterruptedException{ 

    Runnable r1 = new Runnable() { 
     public void run() { 
      while(true){ 
      x = x + 1; 
      System.out.println("increment x"); 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      } 
     } 
    }; 

    Runnable r2 = new Runnable() { 
     public void run() { 
      while(true){ 
      System.out.println("x is "+x); 
      } 
     } 
    }; 
     Thread t1 = new Thread(r1); 
     Thread t2 = new Thread(r2); 
     t1.start(); 
     t2.start(); 

//的Thread.sleep (5000);

} 

}

是這樣的..但保持在上述

+1

請給出解釋。 –

+0

這只是爲了展示它應該如何工作。像這樣訪問一個靜態變量可能會導致錯誤。兩個線程可能會同時使用相同的變量,導致不可預知的結果。爲了避免使用與下面解釋的@JB同步。 – user3340677

3

您的run()方法只增加x,打印它並返回。只要run方法返回,線程就會停止運行。如果您想要永遠運行某些東西,則需要在run()方法中使用循環。而且,在沒有任何同步的情況下訪問共享變量將不會導致可預測的結果。你的x變量應該至少是易變的。最後,Thread.sleep()是一個靜態方法。因此,應使用類名叫做:

Thread.sleep(5000L); 

它使當前線程睡眠。

下面是一個例子,其中一個線程增量X每500毫秒時間,一個其他線程打印X每100毫秒時間,並且兩個線程都在5秒鐘後中斷:

public class ThreadExample { 
    private static volatile int x; 

    private static class Incrementer implements Runnable { 
     @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       x++; 
       try { 
        Thread.sleep(500L); 
       } 
       catch (InterruptedException e) { 
        return; 
       } 
      } 
     } 
    } 

    private static class Reader implements Runnable { 
     @Override 
     public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
       System.out.println(x); 
       try { 
        Thread.sleep(100L); 
       } 
       catch (InterruptedException e) { 
        return; 
       } 
      } 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 
     Thread t1 = new Thread(new Incrementer()); 
     Thread t2 = new Thread(new Reader()); 
     t1.start(); 
     t2.start(); 

     try { 
      Thread.sleep(5000L); 
     } 
     finally { 
      t1.interrupt(); 
      t2.interrupt(); 
     } 
    } 
} 
+0

但是,如果我在run方法中添加while循環,當第一個線程t1)開始運行,第二個(t2)永遠不會開始運行。 – user1914367

+1

你爲什麼這麼認爲?線程的全部要點是能夠同時運行。你的程序目前啓動數十個線程,每個線程都執行一個或兩個操作:增加x並打印它。 –

+0

這不是你想要的嗎?如果不是,請解釋你想要的。第一個線程應該增加5秒鐘的值並在什麼時候停止?第二個線程應該連續打印值並在什麼時候停止?線程是否應該自行停止運行,或者主線程是否要求它們停止運行,如果是,何時運行? –

0

在while循環做心靈點,你每次創建新Threads然後start他們每個人說的就是爲什麼你有這樣行爲。

然後,你將需要移動while循環線程內,使他們LOOL象下面這樣:

public static volatile int x = 0; 

public static void main(String[] args) throws InterruptedException{ 

Runnable r1 = new Runnable() { 
    public void run() { 
     while (true) { 
     x = x + 1; 
     System.out.println("increment x"); 
     this.sleep(5000); 
     } 
    } 
}; 

Runnable r2 = new Runnable() { 
    public void run() { 
     while(true){ 
     System.out.println("x is "+x); 
     } 
    } 
}; 
Thread t1 = new Thread(r1); 
Thread t2 = new Thread(r2); 
t1.start(); 
t2.start(); 
} 

還請注意,您的x變量應該同步存取看到正確的值。

BR。

+0

此代碼仍有問題。至少變量x需要是易失性的或最終AtomicInteger用於線程同步。 – wonhee

+1

同步的目標不是避免死鎖。目標是能夠看到正確的價值。沒有同步的代碼永遠不會死鎖。但它會顯示不正確的結果。 –

0
Thread t1;; 
    Thread t2; 
while(true){ 
     t1 = new Thread(r1); 
     t2= new Thread(r2); 
     t1.start(); 
     t1.sleep(5000); 
     t2.start(); 

} 

你正在添加的代碼是正確的把代碼放在t2.sleep(5000)t2.start()之前。

相關問題