近日于LeetCode看題遇1114 按序打印,獲悉一解法使用了Semaphore,順勢研究,記心得于此。
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供集美網(wǎng)站建設(shè)、集美做網(wǎng)站、集美網(wǎng)站設(shè)計、集美網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、集美企業(yè)網(wǎng)站模板建站服務(wù),十余年集美做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
此解視Semaphore為鎖,以保證同一時刻單線程的順序執(zhí)行。在此原題上,我作出如下更改。
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreDemo { static Semaphore A; static Semaphore B; static Semaphore C; public static void main(String[] args) throws InterruptedException { A = new Semaphore(1); B = new Semaphore(0); C = new Semaphore(0); ExecutorService ex=Executors.newFixedThreadPool(10); for (int i = 0; i <7; i++) { ex.execute(new R1()); ex.execute(new R2()); ex.execute(new R3()); } ex.shutdown(); } public static class R1 implements Runnable{ @Override public void run() { try { // A.acquire(); System.out.println("1"+Thread.currentThread().getName()); // B.release(); } catch (Exception e) { e.printStackTrace(); } } } public static class R2 implements Runnable{ @Override public void run() { try { // B.acquire(); System.out.println("2"+Thread.currentThread().getName()); // C.release(); } catch (Exception e) { e.printStackTrace(); } } } public static class R3 implements Runnable{ @Override public void run() { try { // C.acquire(); System.out.println("3"+Thread.currentThread().getName()); // A.release(); } catch (Exception e) { e.printStackTrace(); } } } }
10個線程的常量池中,分別調(diào)用R1,R2,R3的方法多次,控制臺輸出對應(yīng)各方法名拼接執(zhí)行該方法的線程名。多次執(zhí)行結(jié)果各不相同:
1pool-1-thread-1 2pool-1-thread-2 1pool-1-thread-4 3pool-1-thread-6 2pool-1-thread-5 3pool-1-thread-3 1pool-1-thread-7 2pool-1-thread-8 3pool-1-thread-9 3pool-1-thread-1 2pool-1-thread-8 1pool-1-thread-4 3pool-1-thread-1 1pool-1-thread-2 2pool-1-thread-9 1pool-1-thread-10 3pool-1-thread-1 2pool-1-thread-5 1pool-1-thread-6 3pool-1-thread-4 2pool-1-thread-8
1pool-1-thread-1 2pool-1-thread-2 3pool-1-thread-3 1pool-1-thread-4 2pool-1-thread-5 3pool-1-thread-6 1pool-1-thread-7 2pool-1-thread-8 3pool-1-thread-9 1pool-1-thread-10 3pool-1-thread-1 1pool-1-thread-4 2pool-1-thread-8 3pool-1-thread-3 2pool-1-thread-10 1pool-1-thread-2 2pool-1-thread-9 3pool-1-thread-4 1pool-1-thread-7 3pool-1-thread-6 2pool-1-thread-5
方法能調(diào)用,多線程下卻無法保證方法的順序執(zhí)行。使用Semaphore后,代碼為:
package test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreDemo { static Semaphore A; static Semaphore B; static Semaphore C; public static void main(String[] args) throws InterruptedException { A = new Semaphore(1); B = new Semaphore(0); C = new Semaphore(0); ExecutorService ex=Executors.newFixedThreadPool(10); for (int i = 0; i <7; i++) { ex.execute(new R1()); ex.execute(new R2()); ex.execute(new R3()); } ex.shutdown(); } public static class R1 implements Runnable{ @Override public void run() { try { A.acquire(); System.out.println("1"+Thread.currentThread().getName()); B.release(); } catch (Exception e) { e.printStackTrace(); } } } public static class R2 implements Runnable{ @Override public void run() { try { B.acquire(); System.out.println("2"+Thread.currentThread().getName()); C.release(); } catch (Exception e) { e.printStackTrace(); } } } public static class R3 implements Runnable{ @Override public void run() { try { C.acquire(); System.out.println("3"+Thread.currentThread().getName()); A.release(); } catch (Exception e) { e.printStackTrace(); } } } }
多次運行結(jié)果皆能保證1、2、3的順序:
1pool-1-thread-1 2pool-1-thread-2 3pool-1-thread-3 1pool-1-thread-4 2pool-1-thread-5 3pool-1-thread-6 1pool-1-thread-7 2pool-1-thread-8 3pool-1-thread-9 1pool-1-thread-10 2pool-1-thread-1 3pool-1-thread-2 1pool-1-thread-3 2pool-1-thread-4 3pool-1-thread-5 1pool-1-thread-6 2pool-1-thread-9 3pool-1-thread-7 1pool-1-thread-10 2pool-1-thread-8 3pool-1-thread-1
附上api文檔鏈接 Semaphore
A = new Semaphore(1);
B = new Semaphore(0);
C = new Semaphore(0);
進(jìn)入R2、R3方法的線程會執(zhí)行acquire()方法,而B、C中的計數(shù)器為0獲取不到許可,阻塞直到一個可用,或者線程被中斷,不能繼續(xù)執(zhí)行。R1方法中A尚有1個許可可拿到,方法執(zhí)行,并給B發(fā)布一個許可,若B先于A執(zhí)行acquire(),此時B為阻塞狀態(tài),則獲取到剛剛發(fā)布的許可,該線程被重新啟用。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)站標(biāo)題:Java信號量Semaphore的實現(xiàn)
本文路徑:http://www.muchs.cn/article46/ghjghg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、用戶體驗、建站公司、網(wǎng)站維護、外貿(mào)網(wǎng)站建設(shè)、微信公眾號
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)