程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> JDK5新特性之線程同步工具類(三)

JDK5新特性之線程同步工具類(三)

編輯:C++入門知識

JDK5新特性之線程同步工具類(三)


一. Semaphore實現信號燈

Semaphore可以控制同時訪問資源的線程個數, 例如: 實現一個文件允許的並發訪問數.

Semaphore實現的功能就類似廁所有5個坑, 加入有十個人要上廁所, 那麼同時只能有5個人能夠占用, 當5個人中的任何一個人離開後, 其中在等待的另外5個人中就有一個可以占用了. 另外等待的5個人中可以是隨機獲得優先機會, 也可以使按照先來後到的順序獲得機會, 這取決於構造Semaphore對象時傳入的參數選項.

/**
 * Semaphore:信號燈
 */
public class SemaphoreTest {

	public static void main(String[] args) {
		// 創建一個線程池
		ExecutorService es = Executors.newCachedThreadPool(); 
		
		// 允許並發訪問的線程個數為3個
		final Semaphore sp = new Semaphore(3);
		
		// 開啟10個線程
		for (int i = 0; i < 10; i++) {
			es.execute(new Runnable() {
				@Override
				public void run() {
					try {
						sp.acquire(); // 獲取信號燈
						
						System.out.println("線程 " + Thread.currentThread().getName() 
								+ " 進入,當前有 " + (3 - sp.availablePermits()) + " 個並發!"); 
	
						Thread.sleep(2000);
						
						System.out.println("線程 " + Thread.currentThread().getName() + " 即將離開!");
						
						sp.release(); // 釋放信號燈
						System.out.println("線程 " + Thread.currentThread().getName() 
								+ " 離開,當前有 " + (3 - sp.availablePermits()) + " 個並發!");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}

單個Semaphore對象可以實現互斥鎖的功能, 並且可以是由一個線程獲得了"鎖", 再由另一個線程釋放"鎖", 這可應用於死鎖恢復的一些場合.


public class CyclicBarrierTest {

	public static void main(String[] args) {
	
		ExecutorService service = Executors.newCachedThreadPool();
	
		final CyclicBarrier cb = new CyclicBarrier(3);
		
		// 創建3個線程
		for(int i=0;i<3;i++){
			service.execute(new Runnable(){
				@Override
				public void run(){
					try {
						Thread.sleep((long)(Math.random() * 10000));//每個線程“休息的”時間不同   
						System.out.println("線程" + Thread.currentThread().getName()  
								+ "即將到達集合地點1,當前已有" + (cb.getNumberWaiting() + 1) 
								+ "個已經到達," + (cb.getNumberWaiting() == 2 ? "都到齊了,繼續前進":"正在等候"));                       
						
						cb.await(); //先到的等待後到的,當3個都到達時才會繼續向下執行
	
						Thread.sleep((long)(Math.random() * 10000));//每個線程“休息的”時間不同       
						System.out.println("線程" + Thread.currentThread().getName() 
								+ "即將到達集合地點2,當前已有" + (cb.getNumberWaiting() + 1) 
								+ "個已經到達," + (cb.getNumberWaiting() == 2 ? "都到齊了,繼續前進":"正在等候"));
	
						cb.await(); 
	
						Thread.sleep((long)(Math.random()*10000));//每個線程“休息的”時間不同       
						System.out.println("線程" + Thread.currentThread().getName() 
								+ "即將到達集合地點3,當前已有" + (cb.getNumberWaiting() + 1) 
								+ "個已經到達,"+ (cb.getNumberWaiting() == 2 ? "都到齊了,繼續前進":"正在等候"));                     
	
						cb.await();                     
					} catch (Exception e) {
						e.printStackTrace();
					}               
				}
			});
		}
		service.shutdown();
	}
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved