Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-具有固定数量的对象池的有效对象池,并使用wait notify_Java_Design Patterns_Object Pooling_Objectpool - Fatal编程技术网

Java-具有固定数量的对象池的有效对象池,并使用wait 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 {

我试图实现对象池,它有固定数量的对象可用于池,并使用wait if Pool if empty和notify当线程释放对象时

我能够使用以下程序实现上述要求的功能

我想知道实施是否正确,或者从访谈的角度来看是否需要修改?

    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;
    }   

}