java進階:15.4 多線程 - 信號量、原子操作

1. 信號量

計算機科學中,信號量指對共同資源進行訪問控制的對象。在訪問資源之前,線程必須從信號量獲取許可。在訪問完資源之後,這個線程必須將許可返回給信號量。

爲了創建信號量,必須確定許可的數量,同時可選用公平策略。任務通過調用信號量的acquire() 方法來獲得許可,通過調用信號量的release()方法來釋放許可。一旦獲得許可, 信號量中可用許可的總數減1。一旦許可被釋放,信號量中可用許可的總數加1。

	private static Semaphore = new Semaphore(1);
	...
	public void deposit(int amount){
		try{
		     semaphore.acquire();
		     ...
		 }
		 catch(InterruptedException ex){
		 }

		finally{
			semaphore.release();
		}

2. 原子操作

所謂的原子性操作即 不可中斷的操作,比如賦值操作 int i = 5;

原子性操作本身是線程安全的,但是 i++ 這個行爲,事實上是有3個原子性操作組成的。
步驟 1. 取 i 的值
步驟 2. i + 1
步驟 3. 把新的值賦予i
這三個步驟,每一步都是一個原子操作,但是合在一起,就不是原子操作。就不是線程安全的。

換句話說,一個線程在步驟1 取 i 的值結束後,還沒有來得及進行步驟2,另一個線程也可以取 i 的值了。

i++ ,i–, i = i+1 這些都是非原子性操作。
只有int i = 1,這個賦值操作是原子性的。

3. AtomicInteger

JDK6 以後,新增加了一個包 java.util.concurrent.atomic,裏面有各種原子類,比如 AtomicInteger

AtomicInteger 提供了各種自增,自減等方法,這些方法都是原子性的。 換句話說,自增方法 incrementAndGet 是線程安全的,同一個時間,只有一個線程可以調用這個方法。

import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
    public static void main(String[] args) throws InterruptedException {
    	AtomicInteger atomicI =new AtomicInteger();
    	int i = atomicI.decrementAndGet();
    	int j = atomicI.incrementAndGet();
    	int k = atomicI.addAndGet(3); 	
    }  
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章