Java并发-类库新组件 - Semaphore 理解:计数信号量

Pool.java 类

package com.xyw.concurrent.blog;

import java.util.*;
import java.util.concurrent.*;


/*
 * 对象池概念.管理和回收对象,可以签出和签入对象的概念
 */
public class Pool<T> {
	private int size;
	private List<T> items = new ArrayList<T>();
	private volatile boolean[] checkedOut;
	private Semaphore available; // 计数信号量 允许n个任务同时访问这个资源
	public Pool(Class<T> classObject, int size){
		this.size = size;
		checkedOut = new boolean[size]; // 用来表示某个任务是否被签出的情况
		available = new Semaphore(size, true);
		for(int i = 0; i < size; ++i){
			try{
				items.add(classObject.newInstance()); // 现在向其中添加对象
			}catch(Exception e){
				throw new RuntimeException(e);
			}
		}
	}
	public T checkOut() throws InterruptedException{
		available.acquire();
		return getItem(); // 对象签出对象池,这个是重新获得一个可用的对象从对象池中获得
	}
	
	public void checkIn(T x){
		if(releaseItem(x)){
			available.release(); // 对象签入对象池,用于回收对象池
			// 而 semaphore 的真正起到的作用 ,只是 利用并发,进行技术信号量
		}
	}
	private synchronized T getItem(){
		for(int i =0; i< size; ++i){
			if(!checkedOut[i]){
				checkedOut[i] = true;
				return items.get(i); 
			}
		}
		return null;
	}
	private synchronized boolean releaseItem(T item){
		int index = items.indexOf(item);
		if (index == -1) return false;
		if (checkedOut[index]){
			checkedOut[index] = false;
			return true;
		}
		return false; // 这个表示,没有被签出的情况
	} 
}

Fat.java 类

package com.xyw.concurrent.blog;

public class Fat {
	private volatile double  d;
	private static int counter = 0;
	private final int id = counter++;
	public Fat(){
		for(int i = 1; i < 10000; i++){
			d  += (Math.PI + Math.E) / (double) i;
		}
	}
	public void operation(){
		System.out.println(this);
	}
	public String toString(){
		return "Fat id:" + id;
	}
} // 这是个创建代价高昂的对象类型,其构造器运行起来很是费事

SemaphoreDemo.java

package com.xyw.concurrent.blog;

import java.util.*;
import java.util.concurrent.*;

class CheckoutTask<T> implements Runnable{
	private static int counter = 0;
	private final int id = counter++;
	private Pool<T> pool;
	public CheckoutTask(Pool<T> pool){
		this.pool = pool; // 创建的对象池,用于回收线程和产生线程
	}
	public void run(){
		try{
			T item = pool.checkOut(); // 签出一个线程
			System.out.println(this +"checked out" + item); // 产生出一个线程
			TimeUnit.SECONDS.sleep(1); // 产生一个对象,并运行一段时间
			System.out.println(this + "checking in " + item);
			pool.checkIn(item); // 回收对象,到对象池里面
		}catch(InterruptedException e){
			
		}
	}
	public String toString(){
		return "CheckedOutTask" + id + " ";
	}
	
}

public class SemaphoreDemo {
	final static int SIZE = 25;
	public static void main(String[] args) throws Exception{
		final Pool<Fat> pool = new Pool<Fat>(Fat.class,SIZE); // 创建对象池对象
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i = 0; i < SIZE; i++){
			exec.execute(new CheckoutTask<Fat>(pool));
		}
		System.out.println("All CheckoutTasks created");
		List<Fat> list = new ArrayList<Fat>();
		for(int i = 0; i< SIZE; i++){
			Fat f = pool.checkOut();
			System.out.println(i + " main() thread checked out");
			f.operation();
			list.add(f);
		}
		Future<?> blocked = exec.submit(new Runnable(){
			public void run(){
				try{
					pool.checkOut();
				}catch(InterruptedException e){
					System.out.println("checkOut() Interrupted"); 
				}
			}
		}); // 一旦池中对象都被签出,Semaphore 将不再允许执行任何签出操作 block 的方法被Pool忽略。
		TimeUnit.SECONDS.sleep(2);
		blocked.cancel(true);
		System.out.println("checking in objects in" + list);
		for(Fat f : list)
			pool.checkIn(f);
		for(Fat f: list)
			pool.checkIn(f);
		exec.shutdown();
	}
}

运行结果:

CheckedOutTask0 checked outFat id:0

CheckedOutTask2 checked outFat id:2

CheckedOutTask1 checked outFat id:1

CheckedOutTask3 checked outFat id:3

CheckedOutTask4 checked outFat id:4

CheckedOutTask5 checked outFat id:5

CheckedOutTask6 checked outFat id:6

CheckedOutTask7 checked outFat id:7

CheckedOutTask8 checked outFat id:8

CheckedOutTask9 checked outFat id:9

CheckedOutTask10 checked outFat id:10

CheckedOutTask11 checked outFat id:11

CheckedOutTask12 checked outFat id:12

CheckedOutTask13 checked outFat id:13

CheckedOutTask14 checked outFat id:14

CheckedOutTask15 checked outFat id:15

CheckedOutTask16 checked outFat id:16

CheckedOutTask17 checked outFat id:17

CheckedOutTask18 checked outFat id:18

CheckedOutTask19 checked outFat id:19

CheckedOutTask20 checked outFat id:20

CheckedOutTask21 checked outFat id:21

CheckedOutTask22 checked outFat id:22

All CheckoutTasks created

CheckedOutTask23 checked outFat id:23

0 main() thread checked out

Fat id:24

CheckedOutTask2 checking in Fat id:2

CheckedOutTask5 checking in Fat id:5

CheckedOutTask24 checked outFat id:2

CheckedOutTask4 checking in Fat id:4

CheckedOutTask7 checking in Fat id:7

CheckedOutTask3 checking in Fat id:3

CheckedOutTask1 checking in Fat id:1

CheckedOutTask0 checking in Fat id:0

CheckedOutTask9 checking in Fat id:9

CheckedOutTask8 checking in Fat id:8

1 main() thread checked out

Fat id:5

CheckedOutTask11 checking in Fat id:11

CheckedOutTask6 checking in Fat id:6

2 main() thread checked out

Fat id:0

CheckedOutTask10 checking in Fat id:10

3 main() thread checked out

CheckedOutTask13 checking in Fat id:13

CheckedOutTask12 checking in Fat id:12

CheckedOutTask14 checking in Fat id:14

Fat id:1

4 main() thread checked out

Fat id:3

5 main() thread checked out

Fat id:4

6 main() thread checked out

Fat id:6

7 main() thread checked out

Fat id:7

8 main() thread checked out

Fat id:8

CheckedOutTask15 checking in Fat id:15

CheckedOutTask16 checking in Fat id:16

CheckedOutTask21 checking in Fat id:21

CheckedOutTask20 checking in Fat id:20

CheckedOutTask19 checking in Fat id:19

CheckedOutTask22 checking in Fat id:22

CheckedOutTask18 checking in Fat id:18

CheckedOutTask17 checking in Fat id:17

9 main() thread checked out

CheckedOutTask23 checking in Fat id:23

Fat id:9

10 main() thread checked out

Fat id:10

11 main() thread checked out

Fat id:11

12 main() thread checked out

Fat id:12

13 main() thread checked out

Fat id:13

14 main() thread checked out

Fat id:14

15 main() thread checked out

Fat id:15

16 main() thread checked out

Fat id:16

17 main() thread checked out

Fat id:17

18 main() thread checked out

Fat id:18

19 main() thread checked out

Fat id:19

20 main() thread checked out

Fat id:20

21 main() thread checked out

Fat id:21

22 main() thread checked out

Fat id:22

23 main() thread checked out

Fat id:23

CheckedOutTask24 checking in Fat id:2

24 main() thread checked out

Fat id:2

checkOut() Interrupted

checking in objects in[Fat id:24, Fat id:5, Fat id:0, Fat id:1, Fat id:3, Fat id:4, Fat id:6, Fat id:7, Fat id:8, Fat id:9, Fat id:10, Fat id:11, Fat id:12, Fat id:13, Fat id:14, Fat id:15, Fat id:16, Fat id:17, Fat id:18, Fat id:19, Fat id:20, Fat id:21, Fat id:22, Fat id:23, Fat id:2]



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值