Semaphore (sem?? f?r) Meaning:
The semaphore is the ability to declare multiple locks (including a lock: At this point, the amount of mutually exclusive semaphores).
For example: If a room can only accommodate 5 people, the extra person must wait outside the door. How to do it? One solution: Five keys are hanging out of the room, and each one takes a key, and no key can enter the room but wait outside. Each one comes out and puts the key back in place to make it easier for others to enter again.
Common methods
Acquire (): Gets the semaphore, the semaphore internal counter minus 1
Release (): Free semaphore, semaphore internal counter plus 1
Tryacquire (): This method attempts to get the semaphore, if it can get the return true, otherwise returns false
The number of threads that the semaphore controls is determined at the time of declaration. For example:
Semphore s = new Semphore (2);
An example
Implement a function: A print queue, printed by three printers
Package Semaphore;import Java.util.concurrent.semaphore;import Java.util.concurrent.timeunit;import Java.util.concurrent.locks.lock;import Java.util.concurrent.locks.reentrantlock;public class PrintQueue {// Semaphore private Semaphore semaphore;//whether free printer private Boolean freeprinters[];p rivate Lock lockprinters;public PrintQueue () { Initialize three signals semaphore=new semaphore (3); Three free printers freeprinters=new boolean[3]; for (int i=0; i<3; i++) {freeprinters[i]=true; } lockprinters=new Reentrantlock ();} public void PrintJob (Object document) {try {//Get semaphore semaphore.acquire (); int Assignedprinter=getprinter (); Long duration= (Long) (Math.random () *10); System.out.printf ("%s:printqueue:printing a Job in Printer%d during%d seconds\n", Thread.CurrentThread (). GetName (), Assignedprinter,duration); TimeUnit.SECONDS.sleep (duration); Freeprinters[assignedprinter]=true; } catch (Interruptedexception e) {e.printstacktrace (); } finally {//Free the semaphore semaphore.release (); }}private int GetPrinter () {int ret=-1; try {lockprinters.lock (); for (int i=0; i<freeprinters.length; i++) {if (Freeprinters[i]) {ret=i; Freeprinters[i]=false; Break }}} catch (Exception e) {e.printstacktrace (); } finally {Lockprinters.unlock (); } return ret;}}
Declare a job class that uses a print queue:
package semaphore;public class Job implements Runnable { private PrintQueue printQueue; public Job(PrintQueue printQueue){ this.printQueue=printQueue; } @Override public void run() { System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName()); printQueue.printJob(new Object()); System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName()); }}
Test:
package semaphore;public class MainCmd { public static void main (String args[]){ PrintQueue printQueue=new PrintQueue(); //启动12个打印线程 Thread thread[]=new Thread[12]; for (int i=0; i<12; i++){ thread[i]=new Thread(new Job(printQueue),"Thread "+i); } for (int i=0; i<12; i++){ thread[i].start(); }}}
Places to be aware of
1, for the critical section of the semaphore declaration, although you can control the number of thread access, but there is no guarantee that the code block is thread-safe. So the above example uses a lock in the method PrintJob () method to ensure data security.
2, the signal volume also relates to the question of fairness. As with lock fairness, the default is unfair. The fairness of the declaration lock can be displayed through the constructor.
public Semaphore (int permits, Boolean fair)
Application Scenarios
Flow control, which controls the maximum number of threads that can be accessed.
Video capture
Java Concurrency Synchronization helper class semaphore