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();
}
}
本文给出一个示例,模拟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();
}
}
相关文章推荐
- Semaphor控制资源访问的使用方法
- 无法访问,您可能没有权限使用网络资源的解决方法
- Win7旗舰版系统访问共享计算机提示"您可能没有权限使用网络资源"的解决方法
- 使用对象锁与多线程访问资源控制
- .net中多语言资源的访问(使用assemble和卫星assemble的方法)
- “计算机无法访问,您可能没有权限使用网络资源”解决方法
- php使用Cookie控制访问授权的方法
- 使用springMVC实现基于资源的访问控制
- 使用XPathDocument拒绝访问网站外部资源时的两种替代方法
- 无法访问.您可能没有权限使用网络资源.局域网无法访问共享,局域网无法访问打印机的一些方法
- 无法访问.您可能没有权限使用网络资源.局域网无法访问共享,局域网无法访问打印机的一些方法
- j2ee核心模式笔记一——控制客户端访问服务器资源的方法
- 计算机无法访问,您可能没有权限使用网络资源的解决方法
- 关于“计算机无法访问,您可能没有权限使用网络资源....”的解决方法
- php使用Cookie控制访问授权的方法
- 【Java开发】使用Semaphore控制资源访问并发量
- 针对于win8、win10无法访问,您可能没有权限使用网络资源的解决方法
- iis 访问由于凭据无效被拒绝+请求的资源在使用中的解决方法
- [转] "计算机无法访问,您可能没有权限使用网络资源.请与这台服务器的管理员联系以查明您是否有访问权限" 解决方法
- 无法访问,您可能没有权限使用网络资源的解决方法