1. 程式人生 > >Java線程與並發編程實踐----同步器(交換器、信號量)

Java線程與並發編程實踐----同步器(交換器、信號量)

開啟 style pub for 並發 adp ole code 一個

一、交換器

交換器提供了一個線程之間能夠交換對象的同步點。每個線程都會往這個

交換器的exchange()方法傳入一些對象,匹配夥伴線程,同時接受夥伴對象作為返

回值。java.util.conurrent.Exchange<V>實現了交換器。

下面是一個代碼小實例:

import java.util.concurrent.Exchanger;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
  
public class ExchangerTest {  
  
    public static void main(String[] args) {  
        ExecutorService service = Executors.newCachedThreadPool();  
        final Exchanger exchanger = new Exchanger();  
        service.execute(new Runnable(){  
            public void run() {  
                try {                 
  
                    String data1 = "zxx";  
                    System.out.println("線程" + Thread.currentThread().getName() +   
                    "正在把數據" + data1 +"換出去");  
                    Thread.sleep((long)(Math.random()*10000));  
                    String data2 = (String)exchanger.exchange(data1);  
                    System.out.println("線程" + Thread.currentThread().getName() +   
                    "換回的數據為" + data2);  
                }catch(Exception e){  
                      
                }  
            }     
        });  
        service.execute(new Runnable(){  
            public void run() {  
                try {                 
  
                    String data1 = "lhm";  
                    System.out.println("線程" + Thread.currentThread().getName() +   
                    "正在把數據" + data1 +"換出去");  
                    Thread.sleep((long)(Math.random()*10000));                    
                    String data2 = (String)exchanger.exchange(data1);  
                    System.out.println("線程" + Thread.currentThread().getName() +   
                    "換回的數據為" + data2);  
                }catch(Exception e){  
                      
                }                 
            }     
        });       
    }  
}

二、信號量

信號量維護了一組許可證,以約束訪問被限制資源的線程數。當沒有可用

的許可證時,線程的獲取嘗試會一直阻塞,直到其它的線程釋放一個許可證。

java.util.concurrent.Semaphor實現了這一同步器,同時將信號量概念化成一個

維護一組許可證的對象。他有兩個構造器:

Semaphore(int permits)

Semaphore(int permits,boolean fair)

permits指定了許可證的數量,fair是是否設置公平策略,當設置為 false 時,此類不對線

程獲取許可的順序做任何保證。特別地,闖入 是允許的,也就是說可以在已經等待的線程前

為調用 acquire() 的線程分配一個許可,從邏輯上說,就是新線程將自己置於等待線程隊列

的頭部。當公平設置為 true 時,信號量保證對於任何調用獲取方法的線程而言,都按照處

理它們調用這些方法的順序(即先進先出;FIFO)來選擇線程、獲得許可。

示例代碼:

// 創建信號量對象,並給予3個資源
Semaphore semaphore = new Semaphore(3);
// 開啟10條線程
for ( int i=0; i<10; i++ ) {
    new Thread( new Runnbale(){
        public void run(){
            // 獲取資源,若此時資源被用光,則阻塞,直到有線程歸還資源
            semaphore.acquire();
            // 任務代碼
            ……
            // 釋放資源
            semaphore.release();
        }
    } ).start();
}


Java線程與並發編程實踐----同步器(交換器、信號量)