1、synchronized方法。
public synchronized void save(){}
2、synchronized程式碼區塊。
synchronized(object){ }
3、使用volatile變數。
使用volatile修飾域相當於告訴虛擬機器該域可能會被其他執行緒更新,因此每次使用該域就要重新計算,而不是使用暫存器中的值。
4、使用重入鎖定(ReenreantLock)
public void save(int money) { lock.lock(); try { account += money; } finally { lock.unlock(); } }
5、使用ThreadLocal變量,則每個使用該變數的執行緒都取得該變數的副本,副本之間相互獨立,這樣每一個線程都可以隨意修改自己的變數副本,而不會對其他線程產生影響。
6、使用阻塞佇列(LinkedBlockingQueue等)
7、使用原子變數(AtomicInteger等)
總結:
synchronized:
在偶爾會有同步的情況下,synchronized是很合適的。原因在於,編譯程式通常會盡可能的進行最佳化synchronize。 synchronized是在JVM層面上實現的,不但可以透過一些監控工具監控synchronized的鎖定,而且在程式碼執行時出現異常,JVM會自動釋放鎖定。
ReentrantLock:
ReentrantLock提供了多樣化的同步,例如有時間限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競爭不激烈的情形下,效能稍微比synchronized差點。但是當同步非常激烈的時候,synchronized的效能一下子可以下降好幾十倍。而ReentrantLock確能維持常態。 lock是透過程式碼實現的,要確保鎖定一定會被釋放,就必須將unlock()放到finally{}中。
Atomic:
在不激烈情況下,性能比synchronized略遜,而激烈的時候,也能維持常態。激烈的時候,Atomic的表現會優於ReentrantLock一倍左右。
1、synchronized方法。
public synchronized void save(){}
2、synchronized程式碼區塊。
synchronized(object){ }
3、使用volatile變數。
使用volatile修飾域相當於告訴虛擬機器該域可能會被其他執行緒更新,因此每次使用該域就要重新計算,而不是使用暫存器中的值。
4、使用重入鎖定(ReenreantLock)
public void save(int money) { lock.lock(); try { account += money; } finally { lock.unlock(); } }
5、使用ThreadLocal變量,則每個使用該變數的執行緒都取得該變數的副本,副本之間相互獨立,這樣每一個線程都可以隨意修改自己的變數副本,而不會對其他線程產生影響。
6、使用阻塞佇列(LinkedBlockingQueue等)
7、使用原子變數(AtomicInteger等)
總結:
synchronized:
在偶爾會有同步的情況下,synchronized是很合適的。原因在於,編譯程式通常會盡可能的進行最佳化synchronize。 synchronized是在JVM層面上實現的,不但可以透過一些監控工具監控synchronized的鎖定,而且在程式碼執行時出現異常,JVM會自動釋放鎖定。
ReentrantLock:
ReentrantLock提供了多樣化的同步,例如有時間限制的同步,可以被Interrupt的同步(synchronized的同步是不能Interrupt的)等。在資源競爭不激烈的情形下,效能稍微比synchronized差點。但是當同步非常激烈的時候,synchronized的效能一下子可以下降好幾十倍。而ReentrantLock確能維持常態。 lock是透過程式碼實現的,要確保鎖定一定會被釋放,就必須將unlock()放到finally{}中。
Atomic:
在不激烈情況下,性能比synchronized略遜,而激烈的時候,也能維持常態。激烈的時候,Atomic的表現會優於ReentrantLock一倍左右。
以上是有關Java執行緒同步的詳細內容。更多資訊請關注PHP中文網其他相關文章!