package org.jgroups.tests;
import org.jgroups.Global;
import org.jgroups.util.Pool;
import org.jgroups.util.Util;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
/**
* @author Bela Ban
* @since 3.5
*/
@Test(groups=Global.FUNCTIONAL)
public class PoolTest {
public void testSimpleGet() throws Exception {
Pool<Integer> pool=new Pool<>(4, () -> (int)Util.random(10));
List<Lock> locks=grab(pool, 3);
System.out.println("pool = " + pool);
assert pool.getNumLocked() == 3;
assert locks.size() == 3;
}
public void testGet() throws Exception {
Pool<Integer> pool=new Pool<>(4, () -> (int)Util.random(10));
List<Lock> locks=grab(pool, 3);
System.out.println("pool: " + pool);
assert pool.getNumLocked() == 3;
locks.addAll(grab(pool,3));
assert locks.size() == 4;
Pool.Element el=pool.get();
assert el.getLock() == null;
}
public void testGetAndUnlock() {
Pool<Integer> pool=new Pool<>(4, () -> (int)Util.random(10));
List<Lock> locks=new ArrayList<>(4);
for(int i=0; i < 4; i++)
locks.add(pool.get().getLock());
System.out.println("locks = " + locks);
// the same thread can lock the same lock multiple times
assert pool.getNumLocked() > 0 && pool.getNumLocked() <= 4;
locks.forEach(Lock::unlock);
System.out.println("pool = " + pool);
assert pool.getNumLocked() == 0;
}
protected static <T>List<Lock> grab(Pool<T> pool, int num) throws Exception {
List<Lock> retval=new ArrayList<>(num);
for(int i=0; i < num; i++) {
Grabber grabber=new Grabber(pool);
grabber.start();
grabber.join();
retval.addAll(grabber.getLocks());
}
return retval;
}
protected static class Grabber<T> extends Thread {
protected final Pool<T> pool;
protected final List<Lock> locks=new ArrayList<>();
public Grabber(Pool<T> pool) {
this.pool=pool;
}
public List<Lock> getLocks() {
return locks;
}
public void run() {
Pool.Element element=pool.get();
if(element.getLock() != null)
locks.add(element.getLock());
}
}
}