Java-具有固定数量的对象池的有效对象池,并使用wait notify
我试图实现对象池,它有固定数量的对象可用于池,并使用wait if Pool if empty和notify当线程释放对象时 我能够使用以下程序实现上述要求的功能 我想知道实施是否正确,或者从访谈的角度来看是否需要修改?Java-具有固定数量的对象池的有效对象池,并使用wait notify,java,design-patterns,object-pooling,objectpool,Java,Design Patterns,Object Pooling,Objectpool,我试图实现对象池,它有固定数量的对象可用于池,并使用wait if Pool if empty和notify当线程释放对象时 我能够使用以下程序实现上述要求的功能 我想知道实施是否正确,或者从访谈的角度来看是否需要修改? import java.util.ArrayList; import java.util.List; class ObjectPool { static List objects = new ArrayList(); static {
import java.util.ArrayList;
import java.util.List;
class ObjectPool
{
static List objects = new ArrayList();
static
{
objects.add("Object One");
objects.add("Object Two");
}
public Object getObject()
{
synchronized(objects)
{
if(objects.isEmpty())
{
System.out.println(Thread.currentThread().getName() + " waiting as Object Pool is empty");
try {
objects.wait();
System.out.println(Thread.currentThread().getName() + " Got Notification");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object locked = objects.get(objects.size()-1);
objects.remove(locked);
System.out.println(Thread.currentThread().getName() + " got lock of object : "+ locked);
return locked;
}
}
public boolean release(Object released)
{
synchronized(objects)
{
System.out.println(Thread.currentThread().getName() + " releasing Object : "+released);
objects.notify();
return objects.add(released);
}
}
}
public class MainforObjectPool implements Runnable
{
static ObjectPool p = new ObjectPool();
public static void main(String[] args)
{
MainforObjectPool m = new MainforObjectPool();
Thread t1 = new Thread(m,"thread 1");
Thread t2 = new Thread(m,"thread 2");
Thread t3 = new Thread(m,"thread 3");
Thread t4 = new Thread(m,"thread 4");
Thread t5 = new Thread(m,"thread 5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
System.out.println("Main Thread Completed");
}
public void run()
{
Object locked = p.getObject();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.release(locked);
}
}
很久以前,我使用一个与您类似的抽象解决了类似的问题。幸运的是,我保存了它并把它放了起来。为了保持这个答案简短,希望用我的话说清楚,我不会在这里发布全部代码
实施: 您可以拥有一个具有泛型的抽象类,该泛型允许您创建您喜爱的对象的池。是的,我会像这样用favorite,然后就可以了 这个抽象类让它的实现者处理创建/终止对象的逻辑 此类具有锁定和解锁对象的队列 当您
签入池中的对象时,它将进入解锁队列
当您签出池中的对象时,它通过调用抽象方法validate()
来检查该对象是否应该过期。如果此函数返回true
,则对象将移动到锁定队列。如果此函数返回false
,则对象将从池中删除,并通过调用抽象函数expire()
(在此过程中可以使用notify
)。如果要签出的对象未被池化,则将创建该对象并将其放入锁定队列中
守则:
公共抽象类对象池{
私人长到期时间;
私有哈希表已锁定,未锁定;
公共对象池(){
expirationTime=30000;//30秒
锁定=新哈希表();
unlocked=新哈希表();
}
/**
*在具体类中实现。创建要合并的对象。
*/
受保护的抽象T create();
/**
*用于检查对象是否应保持在锁中或释放。
*/
公共抽象布尔验证(TO);
/**
*对象已过期。(是否使用通知?)
*/
公开摘要失效;
公共同步T签出(){
long now=System.currentTimeMillis();
T;
如果(未锁定的.size()>0){
枚举e=unlockes.keys();
而(e.hasMoreElements()){
t=e.nextElement();
if((现在-unlocked.get(t))>expirationTime){
//对象已过期
解锁。移除(t);
过期(t);
t=零;
}否则{
如果(验证(t)){
解锁。移除(t);
锁定。放置(t,现在);
返回(t);
}否则{
//对象验证失败
解锁。移除(t);
过期(t);
t=零;
}
}
}
}
//没有可用对象,请创建一个新对象
t=创建();
锁定。放置(t,现在);
返回(t);
}
公共同步无效签入(T){
锁定。移除(t);
unlocked.put(t,System.currentTimeMillis());
}
公共同步的长getExpirationTime(){
返回到期时间;
}
公共同步的void setExpirationTime(长expirationTime){
this.expirationTime=到期时间;
}
}
我会问以防万一:您是否知道免费提供的对象池实现,例如?除非您将此作为一种编码练习,否则您应该使用现有的库。是的,它需要大量修改。除非你面试的是一个非常初级的角色,否则这种对同步的天真使用会带来巨大的危险。而静态
是错误的TM。你好@BoristheSpider你能分享我所需的修改或任何链接形式,我可以用它来理解正确的实现吗,TM的意思?对不起,但是这些代码没有一个是可以挽救的。我建议抛弃它,学习如何使用。如果您想了解如何正确地实现一个池,那么Apache Commons池就是。另一件事——对于全面的代码审查,您可以尝试一下。
public abstract class ObjectPool<T> {
private long expirationTime;
private Hashtable<T, Long> locked, unlocked;
public ObjectPool() {
expirationTime = 30000; // 30 seconds
locked = new Hashtable<T, Long>();
unlocked = new Hashtable<T, Long>();
}
/**
* Implemented in concrete class. Create an object to be pooled.
*/
protected abstract T create();
/**
* Used to check whether the object should be kept in the lock, or released.
*/
public abstract boolean validate(T o);
/**
* Object expired. (Use notify?)
*/
public abstract void expire(T o);
public synchronized T checkOut() {
long now = System.currentTimeMillis();
T t;
if (unlocked.size() > 0) {
Enumeration<T> e = unlocked.keys();
while (e.hasMoreElements()) {
t = e.nextElement();
if ((now - unlocked.get(t)) > expirationTime) {
// object has expired
unlocked.remove(t);
expire(t);
t = null;
} else {
if (validate(t)) {
unlocked.remove(t);
locked.put(t, now);
return (t);
} else {
// object failed validation
unlocked.remove(t);
expire(t);
t = null;
}
}
}
}
// no objects available, create a new one
t = create();
locked.put(t, now);
return (t);
}
public synchronized void checkIn(T t) {
locked.remove(t);
unlocked.put(t, System.currentTimeMillis());
}
public synchronized long getExpirationTime() {
return expirationTime;
}
public synchronized void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
}