Semaphore使用
Semaphore:訊號量通常用於限制執行緒的數量訪問一些(物理或邏輯)資源。個人理解:限流、控制訪問量。
使用場景:競爭僅有的資源、一個車廂最多可容納多少人數,超載則不能上車,或者每條通道一次僅能n個人進入,剩下的需要排隊等等。。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.Semaphore; /** * 訊號量 * Semaphore限流、控制訪問量 */ public class SemaphoreTest { public static final Logger logger = LoggerFactory.getLogger(SemaphoreTest.class); public static void main(String[] args) { /** * Creates a {@code Semaphore} with the given number of * permits and nonfair fairness setting. * * @param permits the initial number of permits available. *This value may be negative, in which case releases *must occur before any acquires will be granted. */ // public Semaphore(int permits); /** * Creates a {@code Semaphore} with the given number of * permits and the given fairness setting. * * @param permits the initial number of permits available. *This value may be negative, in which case releases *must occur before any acquires will be granted. * @param fair {@code true} if this semaphore will guarantee *first-in first-out granting of permits under contention, *else {@code false} */ // public Semaphore(int permits, boolean fair); //初始化2個訊號量,也就是說同時最多隻能有2個請求的訪問 Semaphore semaphore = new Semaphore(2); //模擬5次呼叫,迴圈5次,開啟5個非同步執行緒 for (int i = 1; i <= 5; i++) { new Thread(() -> { try { //獲得訪問機會 semaphore.acquire(); logger.info(Thread.currentThread().getName() + "獲得訪問機會!"); } catch (InterruptedException e) { e.printStackTrace(); } //假設這裡有一個1秒鐘的任務,阻塞一秒 try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } //釋放許可, logger.info(Thread.currentThread().getName() + "釋放許可,釋放當前執行緒!"); semaphore.release(); logger.info(Thread.currentThread().getName() + "================================================"); }).start(); } } }
Semaphore並不能保證程式的順序和安全性。
輸出日誌:
11:59:54.157 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1獲得訪問機會! 11:59:54.157 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0獲得訪問機會! 11:59:55.165 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0釋放許可,釋放當前執行緒! 11:59:55.165 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1釋放許可,釋放當前執行緒! 11:59:55.165 [Thread-0] INFO com.test.tenant.SemaphoreTest - Thread-0================================================ 11:59:55.165 [Thread-1] INFO com.test.tenant.SemaphoreTest - Thread-1================================================ 11:59:55.165 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2獲得訪問機會! 11:59:55.165 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3獲得訪問機會! 11:59:56.167 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3釋放許可,釋放當前執行緒! 11:59:56.167 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2釋放許可,釋放當前執行緒! 11:59:56.168 [Thread-3] INFO com.test.tenant.SemaphoreTest - Thread-3================================================ 11:59:56.168 [Thread-2] INFO com.test.tenant.SemaphoreTest - Thread-2================================================ 11:59:56.168 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4獲得訪問機會! 11:59:57.172 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4釋放許可,釋放當前執行緒! 11:59:57.173 [Thread-4] INFO com.test.tenant.SemaphoreTest - Thread-4================================================