Java信號量Semaphore的實現(xiàn)

近日于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)

成都app開發(fā)公司