1. 程式人生 > 遊戲 >《小緹娜的奇幻之地》PC和主機解鎖時間公開

《小緹娜的奇幻之地》PC和主機解鎖時間公開

Semaphore  https://www.cnblogs.com/caoleicoding/p/15015067.html

示例程式碼

Semaphore也是jdk1.5引入的元件,它的字面意思是訊號量,但是單從字面翻譯我們是無法得知它的作用的,根據官方註釋以及網上的一些解釋,semaphore簡單來說就是多執行緒執行控制器,它的主要作用就是控制統一時間併發的執行緒數量,從這一特性上看,它最適用的場景就是限流,下面我們通過一段簡單的程式碼來說明它的用法:

  public class Example {
  private static final int THREAD_SIZE = 30;
  private static final Semaphore s = new Semaphore(5);
   
  public static void main(String[] args) {
  ExecutorService executorService = Executors.newFixedThreadPool(THREAD_SIZE);
  for (int i = 0; i < THREAD_SIZE*2; i++) {
  int finalI = i;
  executorService.execute(() -> {
  try {
  s.acquire();
  System.out.println(Thread.currentThread().getName() + " currentTimeMillis: "+ System.currentTimeMillis());
  Thread.sleep(2000);
  System.out.println("thread count: " + finalI);
  s.release();
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
  });
  }
  executorService.shutdown();
  }
  }

簡單說明

在上面的程式碼中,我們定義了一個執行緒池,執行緒池大小為30,同時我們還定義了一個執行緒執行控制器,控制器的大小我們設定為5,也就是說,在當前控制器的作用下,同一時間只允許5個執行緒執行;

線上程內部,線上程執行最開始,我們通過Semaphoreacquire方法獲取執行許可(拿不到執行憑證是無法執行的),你也可以通過tryAcquire方法獲取執行憑證,兩個方法的區別是tryAcquire有一個布林的返回值,是非阻塞的,而acquire是阻塞的,如果拿不到會一直等,關於這一點,官方文件說的很清楚:

執行緒內部我們休眠了兩秒,然後通過release方法釋放Semaphore資源,這樣其他的執行緒才能拿到這個憑證。

最後,我們用一個for迴圈來執行執行緒,迴圈次數我們設定為執行緒池大小的兩倍,然後我們執行上面的程式碼,執行結果大致如下:

從執行結果中我們可以看到,雖然執行緒池大小是30,但是同一時間執行的執行緒只有5個,也就是我們Semaphore的初始化大小。我們可以試著把Semaphore的大小修改下看下執行結果:

初始化大小為10

同一時間有10個執行緒在執行

初始化大小為2

同一時間有2個執行緒在執行。

作用範圍

下面我們把程式碼做一些簡單調整:

我們分別在acquire方法前和release方法後加一行程式碼,這時候我們的semaphore初始化還是2,然後執行下:

我們發現,雖然acquire方法前和release方法之間以及之後的程式碼雖然同一時間只有兩個執行緒在執行,但是之前的程式碼同一時間是有多於兩個執行緒在執行的,這就是說Semaphore只會影響acquire方法前和release方法之間和之後區域的執行緒併發數,影響之後的程式碼是因為acquire方法是阻塞的,如果我們換成tryAcquire應該就是另外一番場景了:

然後執行:

根據執行結果我們發現,這時候acquire方法前和release方法之間以及之後的程式碼都不受限制了,都出現了併發數超過限制數的情況。具體原因,我們前面說了,tryAcquire方法是非阻塞的,所以這時候我們需要人為根據tryAcquire來控制程式碼邏輯,比如直接結束或者進行其他操作:

  boolean b = s.tryAcquire();
  if (!b) {
  // doSomething()
  System.out.println("未拿到訪問許可權");
  return;
  }

總結

如果說我們之前講的鎖,是單執行緒鎖(同一時間只執行一個執行緒訪問),那麼Semaphore更像是一個多執行緒鎖(同一時間允許多個指定執行緒訪問),它也很像我們之前說的令牌桶(限流解決方案),憑令牌資料訪問相關服務,與之不同的是,這裡的Semaphore可以重複使用的,所以它同樣可以用於限流,比如獲取資料庫連線,我們可以通過Semaphore來限制連線數。