Thinking in Java学习笔记 Semaphore控制的资源池

SemaphoreDemo.java

一个资源池Pool,可以由多个线程检出和检入其中的资源,由Semaphore控制同步问题,由数组来记录每个资源的检出/检入状态


CheckoutTask这个线程,启动多个,负责检入检出资源。


资源类Fat,有比较复杂的计算


同时在main()方法中对资源进行了检出和检入操作

package com.test.concurrent;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo {
	static final int SIZE=25;
	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		final Pool<Fat> pool=new Pool(SIZE,Fat.class);
		ExecutorService exec=Executors.newCachedThreadPool();
		for(int i=0;i<SIZE;i++){
			exec.execute(new CheckoutTask(pool));
		}
		System.out.println("All checkoutTask created!!!");
		List<Fat> list=new ArrayList<Fat>();
		for(int i=0;i<SIZE;i++){
			Fat f=pool.checkOut();
			System.out.println(i+" : main() thread check out");
			f.operation();
			list.add(f);
		}
		Future<?> blocked=exec.submit(new Runnable(){
			public void run(){
				try {
					pool.checkOut();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					System.out.println("Checkout Interrupted!!!!!!!!!!!!");
					e.printStackTrace();
				}
			}
		});
		TimeUnit.SECONDS.sleep(2);
		blocked.cancel(true);
		System.out.println("-------------Checking in objects in "+list);
		for(int i=0;i<SIZE;i++){
			Fat item=list.get(i);
			pool.checkIn(item);
		}
		for(Fat f:list){
			pool.checkIn(f);
		exec.shutdown();	
		}
	}

}

class Pool<T>{
	private int size;
	private Semaphore available;
	private volatile boolean checkOut[];
	private List<T> items=new ArrayList<T>();
	public Pool(int size, Class<T> objectClass){
		this.size=size;
		available=new Semaphore(size,true);
		checkOut=new boolean[size];
		for(int i=0;i<size;i++){
			try {
				items.add(objectClass.newInstance());
			} catch (InstantiationException | IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public T checkOut() throws InterruptedException{
			available.acquire();
			return getItem();
	}
	public void checkIn(T t){
		if(releaseItem(t))
			available.release();
	}
	private synchronized T getItem(){
		for(int i=0;i<size;i++){
			if(!checkOut[i]){
				checkOut[i]=true;
				return (T)items.get(i);
			}
		}
		return null;
	}
	private synchronized boolean releaseItem(T item){
		int index=items.indexOf(item);
		if(index<0){
			return false;
		}
		if(checkOut[index]){
			checkOut[index]=false;
			return true;
		}
		return false;
	}
}
class Fat{
	private volatile double d; //prevent optimization
	private static int counter=0;
	private final int id=counter++;
	public Fat(){
		for(int i=0;i<10000;i++){
			d+=(Math.PI+Math.E);
		}
	}
	public String toString(){
		return "Fat id: "+id+"  D:"+d;
	}
	public void operation(){
		System.out.println(this);
	}
}
class CheckoutTask<T> implements Runnable{
	private static int counter=0;
	private final int id=counter++;
	Pool<T> pool;
	public CheckoutTask(Pool<T> pool){
		this.pool=pool;
	}
	@Override
	public void run(){
		try {
			T item=pool.checkOut();
			System.out.println(this+" check out "+item);
			TimeUnit.SECONDS.sleep(1);
			System.out.println(this+" check in "+item);
			pool.checkIn(item);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String toString(){
		return "CheckoutTask id:"+id+"   ";
	}
}


输出为:

All checkoutTask created!!!
0 : main() thread check out
CheckoutTask id:9    check out Fat id: 9  D:58598.74482048422
CheckoutTask id:4    check out Fat id: 4  D:58598.74482048422
CheckoutTask id:23    check out Fat id: 24  D:58598.74482048422
CheckoutTask id:19    check out Fat id: 17  D:58598.74482048422
CheckoutTask id:0    check out Fat id: 0  D:58598.74482048422
CheckoutTask id:16    check out Fat id: 16  D:58598.74482048422
CheckoutTask id:20    check out Fat id: 18  D:58598.74482048422
CheckoutTask id:6    check out Fat id: 6  D:58598.74482048422
CheckoutTask id:11    check out Fat id: 11  D:58598.74482048422
CheckoutTask id:8    check out Fat id: 8  D:58598.74482048422
CheckoutTask id:7    check out Fat id: 7  D:58598.74482048422
CheckoutTask id:10    check out Fat id: 10  D:58598.74482048422
CheckoutTask id:21    check out Fat id: 22  D:58598.74482048422
CheckoutTask id:22    check out Fat id: 19  D:58598.74482048422
CheckoutTask id:17    check out Fat id: 21  D:58598.74482048422
CheckoutTask id:1    check out Fat id: 1  D:58598.74482048422
CheckoutTask id:12    check out Fat id: 15  D:58598.74482048422
CheckoutTask id:18    check out Fat id: 20  D:58598.74482048422
CheckoutTask id:13    check out Fat id: 12  D:58598.74482048422
CheckoutTask id:2    check out Fat id: 2  D:58598.74482048422
CheckoutTask id:14    check out Fat id: 13  D:58598.74482048422
CheckoutTask id:15    check out Fat id: 14  D:58598.74482048422
Fat id: 23  D:58598.74482048422
CheckoutTask id:3    check out Fat id: 3  D:58598.74482048422
CheckoutTask id:5    check out Fat id: 5  D:58598.74482048422
CheckoutTask id:9    check in Fat id: 9  D:58598.74482048422
CheckoutTask id:20    check in Fat id: 18  D:58598.74482048422
CheckoutTask id:16    check in Fat id: 16  D:58598.74482048422
CheckoutTask id:0    check in Fat id: 0  D:58598.74482048422
1 : main() thread check out
Fat id: 16  D:58598.74482048422
2 : main() thread check out
Fat id: 0  D:58598.74482048422
3 : main() thread check out
Fat id: 18  D:58598.74482048422
CheckoutTask id:4    check in Fat id: 4  D:58598.74482048422
CheckoutTask id:23    check in Fat id: 24  D:58598.74482048422
4 : main() thread check out
Fat id: 4  D:58598.74482048422
5 : main() thread check out
Fat id: 24  D:58598.74482048422
CheckoutTask id:12    check in Fat id: 15  D:58598.74482048422
CheckoutTask id:8    check in Fat id: 8  D:58598.74482048422
6 : main() thread check out
Fat id: 15  D:58598.74482048422
7 : main() thread check out
Fat id: 8  D:58598.74482048422
CheckoutTask id:19    check in Fat id: 17  D:58598.74482048422
CheckoutTask id:24    check out Fat id: 9  D:58598.74482048422
8 : main() thread check out
Fat id: 17  D:58598.74482048422
CheckoutTask id:17    check in Fat id: 21  D:58598.74482048422
9 : main() thread check out
Fat id: 21  D:58598.74482048422
CheckoutTask id:14    check in Fat id: 13  D:58598.74482048422
10 : main() thread check out
Fat id: 13  D:58598.74482048422
CheckoutTask id:11    check in Fat id: 11  D:58598.74482048422
11 : main() thread check out
Fat id: 11  D:58598.74482048422
CheckoutTask id:6    check in Fat id: 6  D:58598.74482048422
12 : main() thread check out
Fat id: 6  D:58598.74482048422
CheckoutTask id:5    check in Fat id: 5  D:58598.74482048422
13 : main() thread check out
Fat id: 5  D:58598.74482048422
CheckoutTask id:7    check in Fat id: 7  D:58598.74482048422
14 : main() thread check out
Fat id: 7  D:58598.74482048422
CheckoutTask id:10    check in Fat id: 10  D:58598.74482048422
15 : main() thread check out
Fat id: 10  D:58598.74482048422
CheckoutTask id:21    check in Fat id: 22  D:58598.74482048422
16 : main() thread check out
Fat id: 22  D:58598.74482048422
CheckoutTask id:22    check in Fat id: 19  D:58598.74482048422
17 : main() thread check out
Fat id: 19  D:58598.74482048422
CheckoutTask id:1    check in Fat id: 1  D:58598.74482048422
18 : main() thread check out
Fat id: 1  D:58598.74482048422
CheckoutTask id:18    check in Fat id: 20  D:58598.74482048422
19 : main() thread check out
Fat id: 20  D:58598.74482048422
CheckoutTask id:13    check in Fat id: 12  D:58598.74482048422
20 : main() thread check out
Fat id: 12  D:58598.74482048422
CheckoutTask id:2    check in Fat id: 2  D:58598.74482048422
21 : main() thread check out
Fat id: 2  D:58598.74482048422
CheckoutTask id:15    check in Fat id: 14  D:58598.74482048422
22 : main() thread check out
Fat id: 14  D:58598.74482048422
CheckoutTask id:3    check in Fat id: 3  D:58598.74482048422
23 : main() thread check out
Fat id: 3  D:58598.74482048422
CheckoutTask id:24    check in Fat id: 9  D:58598.74482048422
24 : main() thread check out
Fat id: 9  D:58598.74482048422
Checkout Interrupted!!!!!!!!!!!!
-------------Checking in objects in [Fat id: 23  D:58598.74482048422, Fat id: 16  D:58598.74482048422, Fat id: 0  D:58598.74482048422, Fat id: 18  D:58598.74482048422, Fat id: 4  D:58598.74482048422, Fat id: 24  D:58598.74482048422, Fat id: 15  D:58598.74482048422, Fat id: 8  D:58598.74482048422, Fat id: 17  D:58598.74482048422, Fat id: 21  D:58598.74482048422, Fat id: 13  D:58598.74482048422, Fat id: 11  D:58598.74482048422, Fat id: 6  D:58598.74482048422, Fat id: 5  D:58598.74482048422, Fat id: 7  D:58598.74482048422, Fat id: 10  D:58598.74482048422, Fat id: 22  D:58598.74482048422, Fat id: 19  D:58598.74482048422, Fat id: 1  D:58598.74482048422, Fat id: 20  D:58598.74482048422, Fat id: 12  D:58598.74482048422, Fat id: 2  D:58598.74482048422, Fat id: 14  D:58598.74482048422, Fat id: 3  D:58598.74482048422, Fat id: 9  D:58598.74482048422]
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
at java.util.concurrent.Semaphore.acquire(Unknown Source)
at com.test.concurrent.Pool.checkOut(SemaphoreDemo.java:73)
at com.test.concurrent.SemaphoreDemo$1.run(SemaphoreDemo.java:31)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值