`
i2534
  • 浏览: 182256 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自己写的多线程对象池

    博客分类:
  • util
阅读更多
/**
 * 排版器的一个公用接口 <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对象池.rar

    Delphi多线程DB组件接口特性创建可自动回收的Query对象池,通过指定接口调用线程中的Query处理数据库操作,当请求结束后自动释放外部引用; 简要说明:    TParamItem  管理存储过程的参数;    ...

    易语言多线程数据池模块

    在实践中,易语言多线程数据池模块源码可以作为一个学习和参考的对象,帮助开发者理解和掌握如何在易语言中实现多线程数据管理。通过分析和研究源码,可以深入理解数据池的工作原理,以及如何在易语言中实现并发控制...

    对象池的一个小例子

    在实际开发中,对象池特别适用于那些对象创建成本高且使用频率较高的情况,比如数据库连接、线程、图像处理等场景。 #### 六、总结 通过上述分析,我们可以看出对象池技术通过预创建和复用对象来提高程序的运行...

    c++ 面向对象多线程编程

    在C++编程中,面向对象和多线程是两个重要的概念,它们对于开发高效、并发的软件至关重要。本文将深入探讨这两个主题,并结合C++语言特性进行详细解释。 首先,让我们了解一下面向对象编程(Object-Oriented ...

    高效的,固定大小的对象池

    4. 锁定与同步:在多线程环境下,需要确保对象池的操作是线程安全的。 5. 溢出处理:当对象需求超过池的容量时,需要有合适的策略来处理,如拒绝服务、动态扩展(不适用于固定大小池)或回退到常规的内存分配。 综...

    基于泛型的,高性能的,可指定构造函数及传入参数初始化的,线程安全的,扩展性非常高的传说中的对象池

    基于泛型的,高性能的,可指定构造函数及传入参数初始化的,线程安全的,扩展性非常高的传说中的对象池 详细看: http://blog.csdn.net/luyikk/archive/2010/05/10/5576550.aspx

    基于C++实现多线程连接池MySQL源码+项目说明+详细代码注释.zip

    * 多线程从连接池中取出数据库对象若有取出,`没有等待`调用算法 * 对 连接池中的数据库连接(空间时间长的即调度算法)进行`适当`断开连接 * 共享资源的访问,需要`互斥锁`(生产者消费者问题) ## 单例模式 * `懒汉...

    python多线程池离线安装包.zip

    在实际应用中,你可能还需要关注多线程的同步问题,如锁机制(Lock)、条件变量(Condition)以及事件对象(Event),以防止数据竞争和死锁,确保程序的正确性。同时,理解线程池的工作原理和调优策略,如合理设置...

    unity中的对象池应用

    希望对有关同学有所帮助 使用对象池有几个注意点: 1.虽然对象池可以优化对象利用率,但是对象池也不能无限地存储对象,这样对于内存占用也是急剧...3.假如在多个线程中同时访问统一对象池,要处理好线程安全的问题

    鱼刺多线程模块

    源代码通常由C++或类似的面向对象编程语言编写,因为它提供了对低级内存管理及多线程操作的良好支持。文档可能详细解释了如何使用模块中的各种功能,示例代码则可以帮助初学者快速上手。编译和部署指南将指导用户...

    Java对象池实现源码

    1. **线程安全**:在多线程环境下,确保对象池操作的并发安全性,可以使用`ConcurrentHashMap`或`CopyOnWriteArrayList`等线程安全的数据结构。 2. **对象状态管理**:跟踪每个对象的状态,如是否正在被使用,避免...

    java 多线程操作数据库

    ### Java多线程操作数据库:深入解析与应用 在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入...

    多线程精品资源--从0开始开发 基础库(配置文件读写、日志、多线程、多进程、锁、对象引用计数、内存池、免锁消息队列、.zip

    在IT行业中,多线程和多进程编程是提升软件性能和效率的重要手段,尤其是在服务器端和高并发场景下。这个"多线程精品资源--从0开始开发 基础库"显然是一份全面的学习资料,涵盖了从基础到进阶的多线程编程知识。下面...

    多线程 hbase

    2. **HBase客户端API**:HBase提供了Java客户端API,支持线程安全的`HTablePool`,这个池可以管理多个`HTable`实例,每个实例对应一个HBase表,允许多线程共享和复用这些实例,减少创建和销毁HTable对象的开销。...

    万能对象池【C#实现】

    例如,可以添加线程安全性,通过`lock`关键字或者`Monitor`类保证多线程环境下的正确性;还可以增加对象初始化逻辑,确保返回的对象符合特定状态;甚至可以实现基于类型或特定标识的对象分类管理。 使用对象池的...

    对象池工厂(微型IOC容器)

    2. **线程安全**:在多线程环境中,如何确保对象池的正确性和一致性。 3. **对象生命周期管理**:何时从池中取出对象,使用完毕后如何归还,以及何时回收不再使用的对象。 4. **容量控制**:如何设置合适的池大小以...

    多线程例子 演示多线程使用

    在计算机编程中,多线程是一种并发执行任务的技术,它允许多个子任务在同一时间运行,从而提高了程序的效率和响应性。这个“多线程例子”演示了如何在C++环境中实现多线程功能。下面我们将深入探讨多线程的基本概念...

    VC++多线程编程实例

    在Windows操作系统中,多线程是通过创建和管理线程对象来实现的,这些线程与进程内的其他线程共享同一内存空间。VC++提供了一种直观的方式来创建和管理线程,主要是通过Microsoft Foundation Classes (MFC)库或者...

Global site tag (gtag.js) - Google Analytics