The Semaphore semaphore is primarily used to constrain the amount of physical or logical resources that multiple threads can acquire simultaneously. For example, in the design of various pools.
The semaphore is used to manage a virtual administrative credential for these resources. When a thread obtains a resource, it first obtains the license credentials for a resource. Returns the resource to the pool after the thread has run out, and returns the license credential to the semaphore.
For example:
Example of a pool:
Class Pool {
private static final int max_available = 100;//Maximum number of available resources
Private final Semaphore available = new Semaphore (max_available, true);
Public Object GetItem () throws Interruptedexception {
Available.acquire ();
return Getnextavailableitem ();
}
public void PutItem (Object x) {
if (markasunused (x))
Available.release ();
}
Not a particularly efficient data structure; Just for Demo
Protected object[] Items = ... whatever kinds of items being managed
Protected boolean[] used = new boolean[max_available];//is used
Protected synchronized Object Getnextavailableitem () {
for (int i = 0; i < max_available; ++i) {
if (!used[i]) {
Used[i] = true;
return items[i];
}
}
return null; Not reached
}
Protected synchronized Boolean markasunused (Object item) {
for (int i = 0; i < max_available; ++i) {
if (item = = Items[i]) {
if (Used[i]) {
Used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}}
There are two parameters when the semaphore is initialized, the first parameter is the number of resources available, and the second is fairness parameter. Fairness parameter is a fair variable. Set to False then, when a thread requests acquire, it is directly assigned to the thread, regardless of the thread waiting for the queue to wait anxiously. The fairness of course is the first to first service, if not to obtain a license, the thread will have to hang up first. But use Tryacquire to grab a license voucher directly. Calling a acquire () does not mean that you must call release (), which means that Java does not require it to appear in pairs, but that the code is correct and is designed by its own program.
I wrote it myself. An example of a semaphore:
Package com;
Import java.util.Collections;
Import Java.util.HashSet;
Import Java.util.Set;
Import Java.util.concurrent.Semaphore;
Class Test
{
Private final Semaphore sem;
Private final set<string> Set;
public Test (int bound)
{
This.set = Collections.synchronizedset (New hashset<string> ());
This.sem=new Semaphore (bound,true);
}
Public boolean Add (String str) throws Interruptedexception
{
Boolean result = false;
Sem.acquire ();
try{
Result=set.add (str);
}finally{
if (!result)
{
Sem.release ();
}
}
return result;
}
public boolean remove (String str)
{
Boolean result=set.remove (str);
if (result)
{
Sem.release ();
}
return result;
}
}
public class main{
public static void Main (string[] args)
{
Test test = new test (10);
New Thread () {
public void Run ()
{
int j=0;
for (int i=20;i<40;)
{
System.out.println ("Thread1 run");
try {
Test.add (string.valueof (i));
System.out.println ("Thread1 Add" + (i++));
} catch (Interruptedexception e) {
TODO auto-generated Catch block
E.printstacktrace ();
}
}
System.out.println ("Thread1 stop");
}
}.start ();
New Thread () {
public void Run ()
{
int j=0;
Boolean result=false;
for (int i=0;i<20;)
{
System.out.println ("Thread2 run");
try {
Result=test.add (string.valueof (i));
if (result) System.out.println ("Thread2 Add" + (i++));
} catch (Interruptedexception e) {
TODO auto-generated Catch block
E.printstacktrace ();
}
}
System.out.println ("Thread2 stop");
}
}.start ();
New Thread () {
public void Run ()
{
int i=0,j=0;
Boolean result=false;
while (I<40)
{
j + +;
j=j%40;
System.out.println ("Thread3 run");
Result=test.remove (String.valueof (j));
if (result) System.out.println ("Remove" + (i++));
}
System.out.println ("Thread3 stop");
}
}.start ();
}
}
Java Semaphore semaphore