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

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();  
    }
}


猜你喜欢

转载自blog.csdn.net/linchunquan/article/details/22414019
今日推荐