[Concurrent] DSL pour ExecutorService
Bonjour,
j'ai dans le code de ma boite de nombreuses fois le même type de code concernant java.util.concurrent.ExecutorService.
du coup pour me simplifier la vie j'ai écris ce petit DSL. qui permet de lancer et synchroniser les threads de cette façon:
Code:
1 2 3 4 5 6 7 8 9 10
| Boolean res = Executor.newExecutor(listRunnables)
.awaitTermination(5, TimeUnit.SECONDS)
.onTermination(() -> {
System.out.println("termination");
})
.onTimeout(() -> {
System.out.println("timeout");
})
.interuptOnTimeout()
.execute(); |
la classe.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
| package fr.ouranos.util;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Executor DSL for ExecutorService.<br />
* create execute and wait termination.<br />
*<pre> Boolean res = Executor.newExecutor(listRunnables)
* .awaitTermination(5, TimeUnit.SECONDS)
* .onTermination(() -> {
* System.out.println("termination");
* })
* .onTimeout(() -> {
* System.out.println("timeout");
* })
* .interuptOnTimeout()
* .execute();
*</pre>
* if "awaitTermination" is not set, "execute" launch all runnable and return true without waiting ends.<br />
* if "awaitTermination" is set, "execute" launch all runnable, wait the ends, and return true if all runnable are end, or false on timeout<br />
* if "onTermination" is set, "onTermination" is executed when all runnable are ends.<br />
* if "onTimeout" is set, "onTimeout" is executed when the timeout is reached.<br />
* if "interuptOnTimeout" all runnables are stoped when the timeout is reached.<br />
* if "interuptOnTimeout" is not set, all runnables continues after the timeout is reached.<br />
*/
public class Executor
{
/**
* create executor for a Runnable List
* @param listRunnable
* @return new Executor
*/
public static Executor newExecutor(List<Runnable> listRunnable){
return new Executor(listRunnable);
}
/**
* create executor for one Runnable
* @param runnable
* @return new Executor
*/
public static Executor newExecutor(Runnable runnable){
return new Executor(runnable);
}
private List<Runnable> listRunnable;
private long timeout = 0;
private TimeUnit unit = null;
private Action onTermination;
private Action onTimeout;
private Boolean interupt = Boolean.FALSE;
private Executor(List<Runnable> listRunnable){
this.listRunnable = listRunnable;
}
private Executor(Runnable runnable){
this.listRunnable = Collections.singletonList(runnable);
}
/**
* add await option<br />
* if "awaitTermination" is not set, "execute" launch all runnable and return true without waiting ends.<br />
* if "awaitTermination" is set, "execute" launch all runnable, wait the ends, and return true if all runnable are end, or false on timeout.
* @param timeout
* @param unit
* @return this
*/
public Executor awaitTermination(long timeout, TimeUnit unit){
this.timeout = timeout;
this.unit = unit;
return this;
}
/**
* add termination event handler<br />
* if "onTermination" is set, "onTermination" is executed when all runnable are ends.
* @param onTermination
* @return this
*/
public Executor onTermination(Action onTermination){
this.onTermination = onTermination;
return this;
}
/**
* add timeout event handler<br />
* if "onTimeout" is set, "onTimeout" is executed when the timeout is reached.
* @param onTimeout
* @return this
*/
public Executor onTimeout(Action onTimeout){
this.onTimeout= onTimeout;
return this;
}
/**
* set interupt option<br .>
* Stop all runnables when the timeout is reached.<br />
* if "interuptOnTimeout" is not set, all runnables continues after the timeout is reached.<br />
* @return this
*/
public Executor interuptOnTimeout(){
this.interupt = Boolean.TRUE;
return this;
}
/**
* execute all runnables with options.
* @return true if "awaitTermination" is not set, true if all runnable are end, false if the timeout is reached.
* @throws InterruptedException
*/
public Boolean execute() throws InterruptedException {
Boolean result = Boolean.FALSE;
if (0 == listRunnable.size()) {
result = Boolean.TRUE;
} else {
final ExecutorService executor = Executors.newFixedThreadPool(listRunnable.size());
for(final Runnable r : listRunnable){
executor.execute(r);
}
executor.shutdown();
if(null != unit) {
if (executor.awaitTermination(timeout, unit)) {
if (null != onTermination) {
onTermination.invoke();
}
result = Boolean.TRUE;
} else {
if (interupt) {
executor.shutdownNow();
}
if (null != onTimeout) {
onTimeout.invoke();
}
}
}else {
result = Boolean.TRUE;
}
}
return result;
}
@FunctionalInterface
public interface Action {
void invoke();
}
} |
et la classe de tests qui va avec
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
| package fr.ouranos.util;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ExecutorTest
{
Logger LOGGER = LoggerFactory.getLogger(ExecutorTest.class);
private Runnable longRunnable;
private List<Runnable> listRunnables;
@Before
public void init() throws Exception{
//runnable sleeping 100 miliseconds
longRunnable = new Runnable()
{
@Override
public void run(){
System.out.println("run");
try{
Thread.sleep(100);
}catch(InterruptedException e){
System.err.println(e.getMessage());
return;
}
}
};
//list of runnables without sleeping.
listRunnables = Collections.singletonList(new Runnable()
{
@Override
public void run(){
System.out.println("run");
}
});
}
/*
* execute empty runnables list
*/
@Test
public void executeEmpty() throws Exception{
Boolean res = Executor.newExecutor(Collections.emptyList())
.awaitTermination(5, TimeUnit.SECONDS)
.execute();
assertTrue("runnables", res);
}
/*
* execute runnables without wait
*/
@Test
public void executeNoWait() throws Exception{
Boolean res = Executor.newExecutor(Collections.emptyList())
.execute();
assertTrue("runnables", res);
}
/*
* execute runnables and wait ends
* and then print "termination"
*/
@Test
public void executeOneTermination() throws Exception{
Boolean res = Executor.newExecutor(listRunnables)
.awaitTermination(5, TimeUnit.SECONDS)
.onTermination(() -> {
System.out.println("termination");
})
.execute();
assertTrue("runnables", res);
}
/*
* execute runnables and wait ends
*/
@Test
public void executeOne() throws Exception{
Boolean res = Executor.newExecutor(listRunnables)
.awaitTermination(5, TimeUnit.SECONDS)
.execute();
assertTrue("runnables", res);
}
/*
* execute runnables and wait 10 microseconds
* then print "timeout"
*/
@Test
public void executeOneOnTimeout() throws Exception{
Boolean res = Executor.newExecutor(longRunnable)
.awaitTermination(10, TimeUnit.MICROSECONDS)
.onTimeout(() -> {
System.out.println("timeout");
})
.execute();
assertFalse("runnables", res);
}
/*
* execute runnables and wait 10 microseconds (tiemout)
*/
@Test
public void executeOneTimeout() throws Exception{
Boolean res = Executor.newExecutor(longRunnable)
.awaitTermination(10, TimeUnit.MICROSECONDS)
.execute();
assertFalse("runnables", res);
}
/*
* execute runnables and wait 10 microseconds
* then print "timeout" and interupt all runnables
*/
@Test
public void executeInteruptOnTimeout() throws Exception{
Boolean res = Executor.newExecutor(longRunnable)
.awaitTermination(10, TimeUnit.MICROSECONDS)
.onTimeout(() -> {
System.out.println("timeout");
})
.interuptOnTimeout()
.execute();
assertFalse("runnables", res);
}
/*
* execute runnables and wait 10 microseconds
* then interupt all runnable
*/
@Test
public void executeInteruptTimeout() throws Exception{
Boolean res = Executor.newExecutor(longRunnable)
.awaitTermination(10, TimeUnit.MICROSECONDS)
.interuptOnTimeout()
.execute();
assertFalse("runnables", res);
}
} |
A+JYT