Java中怎么控制線程訪問資源的數量
在API中是這樣來描述Semaphore
的
Semaphore 通常用于限制可以訪問某些資源(物理或邏輯的)的線程數目。
一個計數信號量。從概念上講,信號量維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire()
,然后再獲取該許可。每個release()
添加一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可對象,Semaphore
只對可用許可的號碼進行計數,并采取相應的行動。
例如,下面的類使用信號量控制線程并發的數量
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;public class TestSemaphore { /** * @param args */ public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); final Semaphore sp = new Semaphore(3,true); for(int i=0;i<10;i++){ Runnable runnable = new Runnable() { @Override public void run() { try { sp.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(sp.availablePermits()); System.out.println("線程 "+ Thread.currentThread().getName() +"進入,已有"+ (3-sp.availablePermits())+ "并發") ; try { Thread.sleep((long) (Math.random()*3000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("線程 "+Thread.currentThread().getName() +"即將離開 " ); sp.release(); System.out.println("線程 "+Thread.currentThread().getName() +"離開 ,已有"+ (3-sp.availablePermits()) + "并發"); } }; pool.execute(runnable); } } } </pre> 再例如可以通過信號量來控制線程訪問資源:<pre class="brush:java; toolbar: true; auto-links: false;"> import java.util.concurrent.Semaphore; public class DownloadThread { private static int in_index = 0; private static int out_index = 0; private static int buffer_count = 100; public static boolean g_downloadComplete; private static Semaphore g_seFull = new Semaphore(0); private static Semaphore g_seEmpty = new Semaphore(buffer_count); public static boolean getBlockFromNet(int in_index) { int i = 0; while (i < 10000) i++; if (in_index < buffer_count - 1) return false; else return true; } public static void writeBlockToDisk(int out_index) { int i = 0; while (i < 100000) i++; } /** * @param args */ public static void main(String[] args) { g_downloadComplete = false; Thread threadA = new Thread() { public void run() { proA(); } }; Thread threadB = new Thread() { public void run() { proB(); } }; threadB.start(); threadA.start(); } public static void proA(){ while (g_seFull.availablePermits() < buffer_count) { try { g_seEmpty.acquire(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } g_downloadComplete = getBlockFromNet(in_index); in_index = (in_index + 1) % buffer_count; g_seFull.release(); System.out.println("download a block " + in_index); if (g_downloadComplete) break; } } public static void proB(){ while (g_seEmpty.availablePermits() > 0) { try { g_seFull.acquire(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } writeBlockToDisk(out_index); out_index = (out_index + 1) % buffer_count; g_seEmpty.release(); System.out.println("write a block " + out_index); if (g_downloadComplete && out_index == in_index) break; } } } </pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!