/**
* 排版器的一个公用接口 <br>
* 实现此接口的排版器,需要有无参数的构造方法供实例化.<br>
*
*/
public interface ILayouter {
/**
* 排版
*/
void layout();
/**
* 重置
*/
void reset();
/**
* 销毁
*/
void dispose();
}
public class LeafLayouter implements ILayouter {
private static AtomicInteger ai = new AtomicInteger(0);
public LeafLayouter() {
ai.incrementAndGet();
}
public void dispose() {
}
public void layout() {
System.out.println(Thread.currentThread().getName() + ":"
+ this.hashCode() + "#" + ai.get() + "#==>layout!");
}
public void reset() {
System.out.println(Thread.currentThread().getName() + ":"
+ this.hashCode() + "#" + ai.get() + "#==>reset!");
}
}
class LayouterFactory {
static <T extends ILayouter> T newInstance(Class<T> c) {
try {
return c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
/**
* 排版器的对象池 <br>
* 所有获取的排版器在使用完毕后必须显式释放,否则将可能产生死锁.<br>
*
*/
public final class LayouterPool {
/**
* 日志
*/
private static Logger _log;
/**
* 排版器管理器的缓存
*/
private Map<Class<?>, LayoterHandler<?>> poolCache;
/**
* 私有构造方法.初始化.
*/
private LayouterPool() {
this.poolCache = new HashMap<Class<?>, LayoterHandler<?>>();
}
/**
* safe and easy lazy init.
*/
private static class PoolHolder {
private static final LayouterPool pool = new LayouterPool();
}
/**
* 获取排版器缓存池的唯一示例
*
* @return 排版器缓存池
*/
public static LayouterPool getInstance() {
_log = Logger.getLogger(LayouterPool.class.getName());
_log.setLevel(Level.WARNING);
return PoolHolder.pool;
}
/**
* 获取一个叶子排版器,在获取到可用排版器之前将一直阻塞.
*
* @return 叶子排版器
*/
public LeafLayouter getLeafLayouter() {
return this.getHandler(LeafLayouter.class, 10).get();
}
/**
* 获取排版器管理器
*
* @param c
* 排版器的类
* @param maxCount
* 最大可存在多少排版器
* @return 排版器管理器
*/
@SuppressWarnings("unchecked")
private synchronized <T extends ILayouter> LayoterHandler<T> getHandler(
Class<T> c, int maxCount) {// 这是一个比较快的操作
LayoterHandler<T> handler = (LayoterHandler<T>) this.poolCache.get(c);
if (handler == null) {
// synchronized (this.poolCache) {//这个不会起作用的
handler = new LayoterHandler<T>(c, maxCount);
this.poolCache.put(c, handler);
// }
}
return handler;
}
/**
* 释放一个排版器<br>
* 被释放的排版器将被重置后重复利用.
*
* @param layouter
* 排版器
*/
@SuppressWarnings("unchecked")
public void release(ILayouter layouter) {// 不用同步,加锁就死锁
if (layouter == null) {
return;
}
LayoterHandler<ILayouter> handler = (LayoterHandler<ILayouter>) this.poolCache
.get(layouter.getClass());
if (handler != null) {
handler.release(layouter);
}
}
/**
* 排版器管理器<br>
* 此管理器负责产生,给予和释放排版器.<br>
* 如果没用可用的排版器,将一直阻塞直到有可用的排版器出现.
*/
private class LayoterHandler<T extends ILayouter> {
/**
* 最大容量
*/
private int capacity;
/**
* 空闲的排版器
*/
private Queue<T> idlers;
/**
* 使用中的排版器
*/
private List<T> rusher;
/**
* 排版器类
*/
private Class<T> clazz;
/**
* 可用的排版器信号
*/
private Semaphore semaphore;
/**
* 构造一个排版器的管理器.
*
* @param c
* 排版器的类
* @param capacity
* 最大容量
*/
LayoterHandler(Class<T> c, int capacity) {
this.clazz = c;
this.capacity = capacity;
this.idlers = new ArrayBlockingQueue<T>(this.capacity);
this.rusher = new ArrayList<T>(this.capacity);
this.semaphore = new Semaphore(this.capacity);
}
/**
* 获取排版器.<br>
* 在排版器序列中有空闲的排版器器时,返回任意的可用排版器.<br>
* 没有空闲的排版器时,判断序列容量是否到达最大容量
* <ol>
* <li>否:则新建一个排版器返回</li>
* <li>是:则阻塞当前线程直到有空闲的排版器,返回可用的排版器</li>
* </ol>
*
* @return 排版器
*/
T get() {
try {
this.semaphore.acquire();
} catch (InterruptedException e) {
_log.log(Level.SEVERE, e.getMessage(), e);
}
T t = this.idlers.poll();
if (t == null) {
t = LayouterFactory.newInstance(this.clazz);
}
this.rusher.add(t);
return t;
}
/**
* 释放一个排版器
*
* @param t
* 排版器
*/
void release(T t) {
if (t == null) {
return;
}
t.reset();
if (this.idlers.offer(t)) {
this.rusher.remove(t);
this.semaphore.release();
}
}
}
}
public class LayouterTest {
public static void main(String[] args) {
for (int i = 0; i < 200; i++) {
new Thread() {
@Override
public void run() {
LayouterPool instance = LayouterPool.getInstance();
// System.out.println(instance);
ILayouter layouter = instance.getLeafLayouter();
layouter.layout();
try {
sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
instance.release(layouter);
}
}.start();
}
}
}
分享到:
相关推荐
Delphi多线程DB组件接口特性创建可自动回收的Query对象池,通过指定接口调用线程中的Query处理数据库操作,当请求结束后自动释放外部引用; 简要说明: TParamItem 管理存储过程的参数; ...
基于泛型的,高性能的,可指定构造函数及传入参数初始化的,线程安全的,扩展性非常高的传说中的对象池 详细看: http://blog.csdn.net/luyikk/archive/2010/05/10/5576550.aspx
* 多线程从连接池中取出数据库对象若有取出,`没有等待`调用算法 * 对 连接池中的数据库连接(空间时间长的即调度算法)进行`适当`断开连接 * 共享资源的访问,需要`互斥锁`(生产者消费者问题) ## 单例模式 * `懒汉...
希望对有关同学有所帮助 使用对象池有几个注意点: 1.虽然对象池可以优化对象利用率,但是对象池也不能无限地存储对象,这样对于内存占用也是急剧...3.假如在多个线程中同时访问统一对象池,要处理好线程安全的问题
对象池的一个小例子,可以参考一下,个人感觉还可以。
多线程精品资源--从0开始开发 基础库(配置文件读写、日志、多线程、多进程、锁、对象引用计数、内存池、免锁消息队列、
内容索引:Delphi源码,数据库应用,多线程 Delphi多线程DB组件测试程序,利用接口特性创建可自动回收的Query对象池,通过指定接口调用线程中的Query处理数据库操作,当请求结束后自动释放外部引用; 有如下特性...
从TThread派生的多线程实例可以构成Delphi的多线程应用程序。 当一个应用程序运行时,应用程序就被载入内存准备执行。此时,它成为包含一个或多个线程的进程,每个线程含有数据、代码和系统资源。线程执行应用...
• 我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决? • Invoke,BeginInvoke干什么用的,内部是怎么实现的 • 每个线程都有消息队列吗? • 为什么Winform不允许跨线程修改UI线程控件的值 ...
利用接口特性构建可自动回收的Query对象池 构建一个线程池,外部通过指定接口调用线程中的Query处理数据库操作,当外部使用完成后,依据接口生存期自管理的特性释放外部的引用; 特性: 1. 线程内查询,外部调用...
1.讲解了Java多线程的基础, 包括Thread类的核心API的使用。2.讲解了在多线程中对并发访问的控制, 主要就是synchronized的使用, 由于此关键字在使用上非常灵活, 所以书中用了很多案例来介绍此关键字的使用, 为...
从0开始开发 基础库(配置文件读写、日志、多线程、多进程、锁、对象引用计数、内存池、免锁消息队列、免锁数据缓冲区、进.zip
下面通过一个简单的样例来说明如何利用apache common pool来应用对象池。 假定我现在有一个任务,就是对一堆字符串进行格式化,为了加快速度,采用了多线程的方式允许,而格式化则是通过对象StringFormat来实现。 ...
包含定义代码和测试代码,代码不复杂,有注释,池对象存取时间复杂度为常数级,多线程测试速度可达千万次/秒。 使用方法如下: 1.定义池,例如: FastPool<std::string> pool; 2.往池添加对象,例如: pool.Add(...
还记得JeffryRichter在《Appiled.NETFrameworkProgramming》里的那个利用对象复苏设计的那个对象池吗?且请容许我把代码在这里再贴一遍: 1using System; 2 3using System.Collections; 4 5
使用apache的commons-pool2 构建 FTPClient连接池 有FtpClientFactory、FtpClientPool、FtpConfig、FtpOperate 四个类组成 还有ftp连接池的一些配置参数信息在ftp.properties文件中 注释完整欢迎大家下载使用
tomcat中Servlet对象池 Servlet在不实现SingleThreadModel的情况下运行时是以单个实例模式,如下图,这种情况下,Wrapper容器只会通过反射实例化一个Servlet对象,对应此Servlet的所有客户端请求都会共用此Servlet...
库包含许多可重用的基类: -易于使用的对象池; -帮助项目处理并行化; -快速线程池,可动态调整线程数; -简化常见的线程启动/停止方案; 极快的轻量级信号灯; 具有阻塞的线程安全队列(比BlockingCollection快5...
Semaphore : 用来确保一定资源多线程访问时的上限,例如资源池。 Event : 是最简单的线程间通信的方式,一个线程可以发送信号,其他的线程接收到信号后执行操作。 二、实例 1)Lock & RLock Lock对象的状态可以...