小结:
A、可以将信号量可视化为一个计数器,它可以递增或递减。
B、从概念上讲,信号量维护了一个许可集合,Semaphore对可用的许可进行计数。
C、当计数器的值为0时,它能够使线程等待。
The three steps you must follow when you use a semaphore to implement a critical section and protect the access to a shared resource:
场景:
假设一个服务器资源有限,任意某一时刻只允许3个人同时访问,这时一共来了10个人
package com.test; import java.util.concurrent.Semaphore; public class SemaphoreDemo{ public static void main(String args[]) throws Exception{ final Semaphore semaphore = new Semaphore(3);//一次只允许3个人进行访问 for(int i=0;i<10;i++) { final int no = i; Runnable thread = new Runnable() { public void run (){ try { System.out.println("用户"+no+"连接上了:"); Thread.sleep(300L); semaphore.acquire();//获取执行的许可 System.out.println("用户"+no+"开始访问后台程序..."); Thread.sleep(1000L);//模仿用户访问服务过程 semaphore.release();//释放,允许下一个线程访问后台 System.out.println("用户"+no+"访问结束。"); } catch (InterruptedException e) { e.printStackTrace(); } } }; new Thread(thread).start(); } System.out.println("Main thread end!"); } }
上述代码运行结果如下:
用户1连接上了: 用户3连接上了: 用户4连接上了: 用户2连接上了: 用户0连接上了: 用户5连接上了: 用户7连接上了: Main thread end! 用户6连接上了: 用户8连接上了: 用户9连接上了: 用户3开始访问后台程序... 用户4开始访问后台程序... 用户2开始访问后台程序... 用户4访问结束。 用户3访问结束。 用户7开始访问后台程序... 用户0开始访问后台程序... 用户8开始访问后台程序... 用户2访问结束。 用户5开始访问后台程序... 用户0访问结束。 用户7访问结束。 用户1开始访问后台程序... 用户8访问结束。 用户6开始访问后台程序... 用户1访问结束。 用户9开始访问后台程序... 用户5访问结束。 用户6访问结束。 用户9访问结束。
从结果上可以看出来,10个人同时进来,但是只能同时3个人访问资源,释放一个允许进来一个
Note:
When a thread has finished the use of the shared resource, it must release the semaphore so that the other threads can access the shared resource.
That operation increases the internal counter of the semaphore.
(1)https://howtodoinjava.com/java/multi-threading/binary-semaphore-tutorial-and-example/
(2)https://howtodoinjava.com/java/multi-threading/control-concurrent-access-to-multiple-copies-of-a-resource-using-semaphore/