Hola gente. Después de leerme e intentar comprender el patrón "Object Pool", este es el resultado.
El servicio que escucha "Listener" y ejecuta el parseo de datos en un nuevo hilo llamando a "Parser" desde el pool.public class Listener implements Runnable {
private boolean serviceRun;
private DatagramSocket socket;
private SysLogParser parser;
private DatagramPacket data;
private Thread runThread;
private int bufferSize;
private void init() {
bufferSize = 2048;
setServiceRun(true);
}
@Override
public void run() {
init();
try {
System.out.println("Servicio iniciado\n");
data = new DatagramPacket(new byte[bufferSize], bufferSize);
socket = new DatagramSocket(10100);
while (isServiceRun()) {
try {
socket.receive(data);
parser = ListenerPool.getInstance().checkOut(data.getData());
parser.start();
} catch (IOException e) {
System.out.println("Error Listener: " + e.getMessage());
}
}
} catch (Exception e) {
System.out.println("Error Listener2: " + e.getMessage());
}
}
public boolean isServiceRun() {
return serviceRun;
}
private void setServiceRun(boolean serviceRun) {
this.serviceRun = serviceRun;
}
public void start(){
if (runThread == null){
runThread = new Thread(this);
runThread.start();
}
}
public void stop(){
if (runThread != null){
setServiceRun(false);
}
}
}
La clase que gestiona el pool "ListenerPool" para la clase "Parser"public class ListenerPool {
private static ListenerPool instance = new ListenerPool();
private long expirationTime;
private HashMap<Parser, Long> locked, unlocked;
private ListenerPool() {
expirationTime = 5000;
locked = new HashMap<Parser, Long>();
unlocked = new HashMap<Parser, Long>();
}
public static ListenerPool getInstance() {
createInstance();
return instance;
}
private static void createInstance() {
if (instance == null) {
synchronized(ListenerPool.class) {
if (instance == null) {
instance = new ListenerPool();
}
}
}
}
protected Parser create(byte[] data) {
return new Parser(data);
}
public boolean validate(Parser o) {
return true;
}
public synchronized Parser checkOut(byte[] data) {
long now = System.currentTimeMillis();
Parser t;
if (unlocked.size() > 0) {
Iterator it = unlocked.keySet().iterator();
while (it.hasNext()) {
t = (Parser) it.next();
if ((now - unlocked.get(t)) > expirationTime) {
unlocked.remove(t);
expire(t);
t = null;
} else {
if (validate(t)) {
unlocked.remove(t);
locked.put(t, now);
return (t);
} else {
unlocked.remove(t);
expire(t);
t = null;
}
}
}
}
t = create(data);
locked.put(t, now);
return (t);
}
public synchronized void checkIn(Parser t) {
locked.remove(t);
unlocked.put(t, System.currentTimeMillis());
}
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
El parseador de datos "Parser"public class Parser implements Runnable {
private byte[] data;
private Thread runThread;
public Parser(byte[] data) {
this.data = data;
}
private void show(){
System.out.println(runThread.getId() + "@" + runThread.getName());
}
@Override
public void run() {
this.showLog();
SysLogParserPool.getInstance().checkIn(this);
}
public void start(){
if (runThread == null){
runThread = new Thread(this);
runThread.start();
}
}
}
Si os fijáis en la salida que nos da el método show() de "Parser". ¿No debería de manear hilos con el mismo nombre? Se están creando nuevos hilos de la clase Parser, cuando deberían tener el mismo nombre, ¿no?
Salida11@Thread-1
12@Thread-2
13@Thread-3
14@Thread-4
15@Thread-5
16@Thread-6
17@Thread-7
18@Thread-8
etc....