溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java 信號量Semaphore的實現

發布時間:2020-10-18 06:16:02 來源:腳本之家 閱讀:158 作者:全王工二一 欄目:編程語言

近日于LeetCode看題遇1114 按序打印,獲悉一解法使用了Semaphore,順勢研究,記心得于此。

此解視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();
  }
 } 
  }
 
}

10個線程的常量池中,分別調用R1,R2,R3的方法多次,控制臺輸出對應各方法名拼接執行該方法的線程名。多次執行結果各不相同:

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

方法能調用,多線程下卻無法保證方法的順序執行。使用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();
  }
 } 
  }
 
}

多次運行結果皆能保證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);

進入R2、R3方法的線程會執行acquire()方法,而B、C中的計數器為0獲取不到許可,阻塞直到一個可用,或者線程被中斷,不能繼續執行。R1方法中A尚有1個許可可拿到,方法執行,并給B發布一個許可,若B先于A執行acquire(),此時B為阻塞狀態,則獲取到剛剛發布的許可,該線程被重新啟用。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女