java 訊號量Semaphore

來源:互聯網
上載者:User

標籤:

Semaphore 訊號量主要用於約束多個線程可同時擷取的物理上的或者邏輯上的資源數。比如用在各種池的設計中。

訊號量用於管理這些資源的一個虛擬管理認證。線程在擷取一個資源時,首先要擷取一個資源的許可憑證。當線程用完之後將資源返回池中,並將許可憑證返回給訊號量。

例如:

一個池的例子:

class Pool {

   private static final int MAX_AVAILABLE = 100;//最大可用資源數

   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];//是否被使用

 

   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;

   }

 }}

訊號量初始化時有兩個參數,第一個參數是資源可用數目,第二個是fairness parameter。fairness parameter 是公平變數。設為false那麼,當有一個線程請求acquire時,會直接分給這個線程,而不管等待隊列中焦急等待的眾線程。而公平指的當然就是先來先服務了,如果沒擷取到一個許可,線程就只好先把自己掛起來了。但是使用tryacquire則直接搶一個許可憑證。調用一個acquire()並不意味著必須調用release(),即java不要求其成對出現,但是保證代碼正確,就靠自己的程式設計了。

一下是我自己寫的一個訊號量的例子:

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.