Java tutorial
/* * Copyrights 2002-2013 Webb Fontaine * Developer: Sargis Harutyunyan * Date: 29 juin 2013 * This software is the proprietary information of Webb Fontaine. * Its use is subject to License terms. */ package com.webbfontaine.valuewebb.irms.worker; import com.google.common.collect.Lists; import groovyx.gpars.actor.Actor; import groovyx.gpars.actor.DynamicDispatchActor; import groovyx.gpars.group.NonDaemonPGroup; import groovyx.gpars.group.PGroup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import static com.webbfontaine.twm.urmcore.utils.Preconditions.checkNotNull; public class GParsWorkerPool implements WorkerPool { private static final Logger LOGGER = LoggerFactory.getLogger(GParsWorkerPool.class); private final WorkerFactory workerFactory; private final PGroup pGroup; private List<Actor> workers; public GParsWorkerPool(WorkerFactory workerFactory) { this(workerFactory, new NonDaemonPGroup()); } public GParsWorkerPool(WorkerFactory workerFactory, int threadPoolSize) { this(workerFactory, new NonDaemonPGroup(threadPoolSize)); } private GParsWorkerPool(WorkerFactory workerFactory, PGroup pGroup) { this.workerFactory = workerFactory; this.pGroup = pGroup; } /* Init 'Worker Pool', start() method is not thread safe and should be called only once and before trying submit works */ @Override public void start() { // should be sync call, non thread safe if (workers == null) { workers = createWorkers(pGroup); } } @Override public void run(WorkUnit input) { checkWorkersNotNull(); Actor worker = getWorker(input); worker.send(input); } @Override public <V> V runAndWait(WorkUnit input) throws InterruptedException { checkWorkersNotNull(); Actor worker = getWorker(input); return worker.sendAndWait(input); } @Override public void shutdown() { stopWorkers(); stopThreadPool(); } private <T extends WorkUnit> Actor getWorker(T input) { return workers.get(workerId(input)); } private <T extends WorkUnit> int workerId(T input) { return input.workerId() % workerFactory.getWorkersPoolSize(); } private void checkWorkersNotNull() { checkNotNull(workers, "WorkerPool should by started before trying to submit work to it"); } protected List<Actor> createWorkers(PGroup pGroup) { int workersPoolSize = workerFactory.getWorkersPoolSize(); List<Actor> actors = Lists.newArrayListWithExpectedSize(workersPoolSize); for (int index = 0; index < workersPoolSize; index++) { DynamicDispatchActor actor = createDispatchActor(pGroup); actor.start(); actors.add(actor); } return actors; } private DynamicDispatchActor createDispatchActor(PGroup pGroup) { DynamicDispatchActor dispatchActor = workerFactory.createDispatchActor(); dispatchActor.setParallelGroup(pGroup); return dispatchActor; } private void stopWorkers() { for (Actor worker : workers) { worker.stop(); } for (Actor worker : workers) { try { worker.join(); } catch (InterruptedException e) { LOGGER.warn("", e); } } } private void stopThreadPool() { pGroup.shutdown(); } }