Improved javadoc
This commit is contained in:
parent
bc1b0c1fed
commit
f840a70d5e
@ -4,8 +4,7 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="8cc571ff-831a-43c2-a081-ccf36a30cea0" name="Changes" comment="">
|
<list default="true" id="8cc571ff-831a-43c2-a081-ccf36a30cea0" name="Changes" comment="Improved performance a bit, changed Stack (LIFO) to BlockingQueue(FIFO) with same synchronization principale than Stack and improved test">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/gradle.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/gradle.xml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/TasksThread.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/TasksThread.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/TasksThread.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/fr/altarik/toolbox/asynctasks/TasksThread.java" afterDir="false" />
|
||||||
@ -72,8 +71,16 @@
|
|||||||
<option name="presentableId" value="Default" />
|
<option name="presentableId" value="Default" />
|
||||||
<updated>1663623916232</updated>
|
<updated>1663623916232</updated>
|
||||||
<workItem from="1663623918010" duration="394000" />
|
<workItem from="1663623918010" duration="394000" />
|
||||||
<workItem from="1663662046975" duration="3831000" />
|
<workItem from="1663662046975" duration="6418000" />
|
||||||
</task>
|
</task>
|
||||||
|
<task id="LOCAL-00001" summary="Improved performance a bit, changed Stack (LIFO) to BlockingQueue(FIFO) with same synchronization principale than Stack and improved test">
|
||||||
|
<created>1663666309239</created>
|
||||||
|
<option name="number" value="00001" />
|
||||||
|
<option name="presentableId" value="LOCAL-00001" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1663666309239</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="2" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@ -92,5 +99,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
|
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
|
||||||
|
<MESSAGE value="Improved performance a bit, changed Stack (LIFO) to BlockingQueue(FIFO) with same synchronization principale than Stack and improved test" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Improved performance a bit, changed Stack (LIFO) to BlockingQueue(FIFO) with same synchronization principale than Stack and improved test" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,13 +1,49 @@
|
|||||||
package fr.altarik.toolbox.asynctasks;
|
package fr.altarik.toolbox.asynctasks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A non-blocking small sized time-consuming tasks to executed asynchronously, this was developed mainly to be used to avoid to block main threads with mysql requests in mind
|
||||||
|
*/
|
||||||
public class AsyncTasks {
|
public class AsyncTasks {
|
||||||
|
|
||||||
private static final TasksThread worker = new TasksThread();
|
private static final TasksThread worker = new TasksThread();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this method at startup or before first use of {@link AsyncTasks#addTask(Runnable)}, cause without it, nothing will work
|
||||||
|
* This method declare worker thread and start it, without call it, by calling addTask(Runnable), it'll add your task to Queue, but tasks will never be consumed.
|
||||||
|
*/
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
worker.run();
|
worker.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Method used to add your task to a list of task, task are stored in a FIFO(First-In First-Out) implementation ({@link java.util.concurrent.BlockingQueue}).
|
||||||
|
* As BlockingQueue is a synchronized class, all operations to add or remove elements inside cannot have collisions issues</p>
|
||||||
|
* <p>Example: </p>
|
||||||
|
* <pre>
|
||||||
|
* for(int i = 0; i < 4; i++) {
|
||||||
|
* System.out.println("task " + i);
|
||||||
|
* AtomicInteger atomicI = new AtomicInteger(i);
|
||||||
|
* AsyncTasks.addTask(() -> {
|
||||||
|
* System.out.println(i);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
* <p> Result(output may differ): </p>
|
||||||
|
* <pre>
|
||||||
|
* task 0
|
||||||
|
* task 1
|
||||||
|
* 0
|
||||||
|
* task 2
|
||||||
|
* 1
|
||||||
|
* 2
|
||||||
|
* task 3
|
||||||
|
* 3
|
||||||
|
* </pre>
|
||||||
|
* The worker thread is sleeping if it doesn't have task to execute and wake up if necessary when you add a task
|
||||||
|
* @param function task to be executed
|
||||||
|
* @throws InterruptedException when worker thread or BlockQueue has been interrupted while waiting (which is anormal)
|
||||||
|
*/
|
||||||
public static void addTask(Runnable function) throws InterruptedException {
|
public static void addTask(Runnable function) throws InterruptedException {
|
||||||
if(worker.workerThread.isInterrupted())
|
if(worker.workerThread.isInterrupted())
|
||||||
throw new InterruptedException("Async task thread has been interrupted while waiting for another task, which is anormal, please report this issue to developers");
|
throw new InterruptedException("Async task thread has been interrupted while waiting for another task, which is anormal, please report this issue to developers");
|
||||||
@ -20,6 +56,10 @@ public class AsyncTasks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the numbers of produced tasks which hasn't been consumed yet
|
||||||
|
* @return numbers of produced tasks which hasn't been consumed yet
|
||||||
|
*/
|
||||||
public static int numberOfWaitingTask() {
|
public static int numberOfWaitingTask() {
|
||||||
return worker.tasks.size();
|
return worker.tasks.size();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class TasksThread {
|
/**
|
||||||
|
* Package private class, AsyncTasks is the interface user need to interact with it and users should never directly call this class
|
||||||
|
*/
|
||||||
|
class TasksThread {
|
||||||
|
|
||||||
boolean isWaiting = false;
|
boolean isWaiting = false;
|
||||||
final ReentrantLock lock = new ReentrantLock();
|
final ReentrantLock lock = new ReentrantLock();
|
||||||
@ -14,7 +17,7 @@ public class TasksThread {
|
|||||||
|
|
||||||
final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
|
final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
|
||||||
|
|
||||||
public void run() {
|
void run() {
|
||||||
workerThread = new Thread(() -> {
|
workerThread = new Thread(() -> {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -22,7 +22,7 @@ public class AsyncTaskTest {
|
|||||||
AsyncTasks.initialize();
|
AsyncTasks.initialize();
|
||||||
Stack<Integer> results = new Stack<>();
|
Stack<Integer> results = new Stack<>();
|
||||||
for(int i = 0; i < numberOfTasks; i++) {
|
for(int i = 0; i < numberOfTasks; i++) {
|
||||||
System.out.println("[" + new Date() + "] sending task " + i);
|
System.out.println(log("sending task " + i));
|
||||||
AtomicInteger atomicInteger = new AtomicInteger(i);
|
AtomicInteger atomicInteger = new AtomicInteger(i);
|
||||||
AsyncTasks.addTask(() -> {
|
AsyncTasks.addTask(() -> {
|
||||||
System.out.println(log(" task " + atomicInteger.get()));
|
System.out.println(log(" task " + atomicInteger.get()));
|
||||||
@ -30,12 +30,8 @@ public class AsyncTaskTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
while(AsyncTasks.numberOfWaitingTask() != 0) {
|
while(AsyncTasks.numberOfWaitingTask() != 0) {
|
||||||
try {
|
synchronized (this) {
|
||||||
synchronized (this) {
|
wait(20); // wait till last task finish
|
||||||
wait(20); // wait till last task finish
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Integer[] expected = new Integer[numberOfTasks];
|
Integer[] expected = new Integer[numberOfTasks];
|
||||||
|
Loading…
Reference in New Issue
Block a user