论坛首页 Java企业应用论坛

并发编程之使用信号量来限制工作队列的容量

浏览 3556 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-02-18   最后修改:2009-02-18
OO
    并发编程中,经常要用到线程池相结合的工作队列,来实现一个小的线程池与一个大的队列组成的处理框架。这有助于在并发程序中减轻CPU和内存的压力,又为众多任务的并行提供了保证。这时队列往往需要有长度限制,如果使用没有限制的队列来保存请求任务,这同样会危及到内存的管理,把程序置入了不安全的运行环境中。所以,工作队列应该有一个限制队列长度的选项,保证队列不会占用超出既定资源。

    计数信号量(Counting semaphore)用来控制能够同时访问某特定资源的活动的数量,或者同时执行某一给定操作数量。所以,用计数信号量可以实现对资源池或者工作队列的边界。一个Semaphore管理一个有效的许可集;许可的初始量通过构造函数传递给Semaphore。在还存在剩余许可的情况下,活动能够获得许可,并在使用之后释放放可。如果已经没有可用的许可了,那么acquire会被阻塞,直到有可用的为止(或者直到被中断或超时)。release方法向信号量返回一个许可[1]。

下面是一个简单的有界的优先级阻塞队列的实现:
public class BoundedJobBlockingQueue {

	private final BlockingQueue<Job> jobs;

	private final Semaphore sem;

	public BoundedJobBlockingQueue(int bound) {
		jobs = new PriorityBlockingQueue<Job>();
		sem = new Semaphore(bound);
	}

	public boolean put(Job job) throws InterruptedException {
		try {
			sem.acquire();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		boolean wasAdded = false;
		try {
			wasAdded = jobs.add(job);
			return wasAdded;
		} finally {
			if (!wasAdded)
				sem.release();
		}
	}

	public Job take() throws InterruptedException {
		Job job = jobs.take();
		if (job != null)
			sem.release();
		return job;
	}

}


[1]B. Goetz等,Java并发编程实践
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics