I am trying to implement Object Pool which has fixed number of Objects to be available for pool and using wait if pool if empty and notify when a thread releases an object.
I am able to achieve the above required functionality using below program.
I want to know if the implementation is correct or needs any modification from Interview point of view ?
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);
}
}
Long back ago, I solved the similar problem using an abstraction that is similar to yours. Fortunately, I saved it and put it here. For the sake of keeping this answer short and hopefully being clear in my words, I'll not be posting the whole code here.
Implementation:
You can have an abstract class that has a generic which can allow you to create the pools of your favorite objects. Yes, I'll use favorite like this and get away with it
This abstract class lets its implementors handle the logic of creating/expiring objects.
This class has a queue for objects that are locked and unlocked.
When you
checkIn
an object in the pool, it lands in the unlocked queue.When you
checkOut
an object from the pool, it checks whether the object should be expired or not by calling an abstract methodvalidate()
. If this function returnstrue
, the object is then moved to the locked queue. If this function returnsfalse
, then the object is removed from the pool and is expired by calling the abstract functionexpire()
(you can usenotify
in this). If the object to be checked out is not being pooled, then it's created and put in the locked queue.The code: