2015-10-31 23 views
0

在併發編程中,IF語句和循環如while或do原子指令?原子指令:IF和循環

如果不是,有沒有辦法實現他們原子?

編輯:修正了我一些狡猾的英語。

+1

「安撫」併發線程是什麼意思? –

+0

編輯修復它。 我的意思是,有沒有一種方法可以將實際的語句,IFs或循環算作原子指令。 – MBP

+0

存在於任何現代平臺上的最強大的原子操作是比較和交換(CAS)。你可以自己google自己的算法。對於更復雜的操作序列的歸檔原子性,您需要使用其他同步機制,例如鎖定。 – Tsyvarev

回答

0

在Java中,唯一沒有任何額外工作的原子是分配。其他任何情況都需要同步,或者通過聲明方法​​或使用​​塊。您也可以使用java.concurrent中的類 - 它們中的一些使用一些更聰明的機制來確保同步,而不是僅僅聲明方法​​,這往往是緩慢的。


關於if語句,你在評論被問及比較n == m問題:

比較不是原子。必須加載第一個值n(此處值m仍然可以更改),那麼必須加載值m,然後評估實際比較(並且此時nm的實際值可能已經不同比較)。

如果你想它同步,你會做這樣的事情:

public class Test { 

    private static final Object lock = new Object(); 

    public static void main(String[] args) { 
     if (equals(1, 2)) { 
      // do something (not synchronised) 
     } 
    } 

    public static boolean equals(int n, int m) { 
     synchronized (lock) { 
      return n == m; 
     } 
    } 

} 

然而,這提出了一個問題你爲什麼要做到這一點,應該是什麼樣的鎖(什麼的線程是鎖共享)?我希望看到更多關於你的問題的背景,因爲目前我看不到任何這樣做的理由。


你應該還記得:

  • 你不能在原語鎖定(你將不得不兩個值作爲Integer聲明)
  • 鎖定在null將導致NullPointerException
  • 鎖獲取的價值,而不是參考。由於Java中的整數是不可變的,因此爲字段分配一個新值將導致創建一個新的鎖,請參閱下面的代碼。線程t1獲取new Integer(1)上的鎖定,而t2獲取鎖定new Integer(2)。所以即使兩個線程鎖定在n上,他們仍然可以並行執行。
public class Test { 

    private static Integer n = 1; 

    public static void main(String[] args) throws Exception { 
     Thread t1 = new Thread(() -> { 
      synchronized (n) { 
       System.out.println("thread 1 started"); 
       sleep(2000); 
       System.out.println("thread 1 finished"); 
      } 
     }); 
     Thread t2 = new Thread(() -> { 
      synchronized (n) { 
       System.out.println("thread 2 started"); 
       sleep(2000); 
       System.out.println("thread 2 finished"); 
      } 
     }); 

     t1.start(); 
     sleep(1000); 
     n = 2; 
     t2.start(); 

     t1.join(); 
     t2.join(); 
    } 

    private static void sleep(int millis) { 
     try { 
      Thread.sleep(millis); 
     } catch (InterruptedException e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 

你有沒有使用可變AtomicInteger考慮?

0

這些可以有任意大的&需要評估的複雜(即非原子)布爾表達式。一種防止涉及他們的競爭條件的方法(如果這就是「安撫」的意思)是使用某種鎖定機制。

+0

如果被評估的表達式只是比較兩個整數,那麼該如何? if(n == m) while(n == v){} – MBP