您的位置:首页 > 其它

Semaphor控制资源访问的使用方法

2014-03-28 18:24 387 查看
Semaphore是java并发包中提供的用于控制某资源同时被访问的个数的类。Semaphore最重要的两个方法是acquire()和release()。acquire()用于获得访问资源的许可,该方法会阻塞直到有可访问的资源;release用于释放访问资源的许可。
本文给出一个示例,模拟300个线程去获取资源池中的资源,但资源池每次最多只能提供10个资源. 当线程使用完资源后,归还相应的资源,供其他线程继续使用. 

资源类源代码 -

package semaphore;

/**
* 资源类
* @author cclin
*
*/
public class Resource {

//资源名称
private String resourceName;
//资源状态,判断资源是否被占用
private boolean busy;

public Resource(String resourceName) {
super();
this.resourceName = resourceName;
}

public String getResourceName() {
return resourceName;
}

public boolean isBusy() {
return busy;
}

public void setBusy(boolean busy) {
this.busy = busy;
}
}


资源池源代码,基于信号量的资源访问 -
package semaphore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
* 资源池类
* @author cclin
*
*/
public class ResourcePool {

// 资源数目
private static final int RESOURCE_SIZE = 10;
// 构建资源集合
private List<Resource> resources = new ArrayList<Resource>(){{
for(int i=0;i<RESOURCE_SIZE;i++){
add(new Resource("资源"+i));
}
}};
// 控制资源范围的信号量,最多只能提供 RESOURCE_SIZE 个资源被访问
private Semaphore semaphore = new Semaphore(RESOURCE_SIZE);

/**
* 获取资源
* @return
* @throws InterruptedException
*/
public Resource fetchResource() throws InterruptedException{
//获取访问资源的许可
semaphore.acquire();
Resource rs = null;
for(Resource resource : resources){
if(!resource.isBusy()){
//返回一个空闲资源
rs = resource;
//设置资源状态
rs.setBusy(true);
System.out.println("资源池分配"+rs.getResourceName());
break;
}
}
return rs;
}

/**
* 释放资源
*/
public void releaseResource(Resource resource){
//设置资源状态
resource.setBusy(false);
System.out.println("资源池回收"+resource.getResourceName());
//释放一个资源许可
semaphore.release();
}
}


资源消费者源代码 - 
package semaphore;

/**
* 资源消费者类
* @author cclin
*
*/
public class Consumer implements Runnable {

/**
* 消费者名称
*/
private String consumerName;

/**
* 资源池
*/
private ResourcePool rsPool;

public Consumer(String consumerName, ResourcePool rsPool) {
super();
this.consumerName = consumerName;
this.rsPool = rsPool;
System.out.println("创建了"+consumerName);
}

/**
* 使用资源池中分配的资源
* @param rsPool
*/
public void consumeResourceFromPool(){
//从资源池中获取资源
try {
Resource rs = rsPool.fetchResource();
if(rs!=null){
//使用资源
System.out.println(consumerName+"正在使用"+rs.getResourceName());
Thread.sleep(5000);
//使用完毕,释放资源
System.out.println(consumerName+"使用"+rs.getResourceName()+"完毕");
rsPool.releaseResource(rs);
}
else{
System.out.println(consumerName+"无法获得任何资源!");
}

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
consumeResourceFromPool();
}
}


测试代码 - 
package semaphore;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SemaphoreTest {

public static void main(String[]args){
//创建线程池
ExecutorService executorService = Executors.newCachedThreadPool();
ResourcePool rsPool = new ResourcePool();
for (int i = 0; i <= 300; i++) {
executorService.submit(new Consumer("消费者"+i, rsPool));
}
executorService.shutdown();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐