ExecutorService state Listener - java

I am currently building an application that polls some data over a Wireless Sensor Network and process them afterwards to extract the necessary information.
I use an ExecutorService to run the polling Task multiple times (as many as the nodes in the network).
There will be a status Label in the GUI that will print the statuses of the ExecutorService. The statuses will be:
Polling node 1 (2, 3, 4, n)...
Terminating threads...
Polling completed
I post a snippet of the ExecutorServicecode below.
My problem is that "Polling finished" is printed in every single thread that is being stopped and not at the end; while ExecutorService is being shutting down. This is obvious, since every thread runs in parallel with the others.
Please correct me if I am wrong.
threadPool.shutdown();
executes as soon as all the running threads have been finished.
I have to find a way to check/listen to the current state of the ExecutorService and when enters the shutdown state to print the status label.
Any advise would be highly appreciated.
public class ScannerThread extends Thread {
...
private static final int NUM_OF_THREADS = Nodes.COUNT;
private static final int UPDATE_INTERVAL = 200;
private ExecutorService threadPool;
public ScannerThread() {
threadPool = Executors.newFixedThreadPool(NUM_OF_THREADS);
...
setDaemon(true);
}
#Override
public void run() {
// poll data from each node in parallel, in a separate thread
for (Node node : Nodes.COUNT) {
...
PollingTask task = new PollingTask(node.getID());
threadPool. execute(task);
}
// request shutdown of the thread pool
threadPool.shutdown();
try {
// wait for all threads that are currently running
while (!threadPool.awaitTermination(UPDATE_INTERVAL, MILLISECONDS)) {
statusLabel.setText("Terminating threads...");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// polling completed
statusLabel.setText("Polling completed");
}
class PollingTask implements Runnable {
...
private String noteID;
PollingTask(String id) {
noteID = id;
...
}
#Override
public void run() {
...
}
}
}

Related

When kills cacheThreadPool inactive threads? Java

the cacheThreadPool automatically deletes threads if they are inactive for 60 seconds, as far as I know. Only what exactly that means inactive is not clear to me.
My implementation looks like this:
public class ProcessHandler {
private class Worker implements Runnable {
private final LinkedBlockingQueue<MyTask> tasks = new LinkedBlockingQueue<>();
void schedule(List<MyTask> task) {
tasks.addAll(task);
}
#Override
public void run() {
while (true) {
try {
var task = tasks.take();
task.run();
} catch (InterruptedException ie) {
// perhaps, handle somehow
}
}
}
}
private ExecutorService esMultiThread = Executors.newCachedThreadPool();
public void submitProcess(List<MyTask> task){
Worker test = new Worker();
test.schedule(task);
esMultiThread.execute(test);
}
}
I create a Instance of ProcessHandler and then I want to submit task over and over again with submitProcess. Every new call of submitProcess should start a new thread so that everything is processed in parallel, e.g. if I call submitProcess 10 times fast in a row. These tasks should then be processed by a new Thread from the cachedThreadPool.
My question now, while the worker is sleeping, i.e. waiting by take(), will the thread be killed if the worker gets nothing for more than 60 seconds, or does the thread live infinitely because "sleeping" is a state which is not considered inactive by the cacheThreadPool?

Processing tasks in parallel and sequentially Java

In my program, the user can trigger different tasks via an interface, which take some time to process. Therefore they are executed by threads. So far I have implemented it so that I have an executer with one thread that executes all tasks one after the other. But now I would like to parallelize everything a little bit.
i.e. I would like to run tasks in parallel, except if they have the same path, then I want to run them sequentially. For example, I have 10 threads in my pool and when a task comes in, the task should be assigned to the worker which is currently processing a task with the same path. If no task with the same path is currently being processed by a worker, then the task should be processed by a currently free worker.
Additional info: A task is any type of task that is executed on a file in the local file system. For example, renaming a file. Therefore, the task have the attribute path. And I don't want to execute two tasks on the same file at the same time, so such tasks with the same paths should be performed sequentially.
Here is my sample code but there is work to do:
One of my problems is, I need a safe way to check if a worker is currently running and get the path of the currently running worker. By safe I mean, that no problems of simultaneous access or other thread problems occur.
public class TasksOrderingExecutor {
public interface Task extends Runnable {
//Task code here
String getPath();
}
private static class Worker implements Runnable {
private final LinkedBlockingQueue<Task> tasks = new LinkedBlockingQueue<>();
//some variable or mechanic to give the actual path of the running tasks??
private volatile boolean stopped;
void schedule(Task task) {
tasks.add(task);
}
void stop() {
stopped = true;
}
#Override
public void run() {
while (!stopped) {
try {
Task task = tasks.take();
task.run();
} catch (InterruptedException ie) {
// perhaps, handle somehow
}
}
}
}
private final Worker[] workers;
private final ExecutorService executorService;
/**
* #param queuesNr nr of concurrent task queues
*/
public TasksOrderingExecutor(int queuesNr) {
Preconditions.checkArgument(queuesNr >= 1, "queuesNr >= 1");
executorService = new ThreadPoolExecutor(queuesNr, queuesNr, 0, TimeUnit.SECONDS, new SynchronousQueue<>());
workers = new Worker[queuesNr];
for (int i = 0; i < queuesNr; i++) {
Worker worker = new Worker();
executorService.submit(worker);
workers[i] = worker;
}
}
public void submit(Task task) {
Worker worker = getWorker(task);
worker.schedule(task);
}
public void stop() {
for (Worker w : workers) w.stop();
executorService.shutdown();
}
private Worker getWorker(Task task) {
//check here if a running worker with a specific path exists? If yes return it, else return a free worker. How do I check if a worker is currently running?
return workers[task.getPath() //HERE I NEED HELP//];
}
}
Seems like you have a pair of problems:
You want to check the status of tasks submitted to an executor service
You want to run tasks in parallel, and possibly prioritize them
Future
For the first problem, capture the Future object returned when you submit a task to an executor service. You can check the Future object for its completion status.
Future< Task > future = myExecutorService.submit( someTask ) ;
…
boolean isCancelled = future.isCancelled() ; // Returns true if this task was cancelled before it completed normally.
boolean isDone = future.isDone(); // Returns true if this task completed.
The Future is of a type, and that type can be your Task class itself. Calling Future::get yields the Task object. You can then interrogate that Task object for its contained file path.
Task task = future.get() ;
String path = task.getPath() ; // Access field via getter from your `Task` object.
Executors
Rather than instantiating new ThreadPoolExecutor, use the Executors utility class to instantiate an executor service on your behalf. Instantiating ThreadPoolExecutor directly is not needed for most common scenarios, as mentioned in the first line of its Javadoc.
ExecutorService es = Executors.newFixedThreadPool​( 3 ) ; // Instantiate an executor service backed by a pool of three threads.
For the second problem, use an executor service backed by a thread pool rather than a single thread. The executor service automatically assigns the submitted task to an available thread.
As for grouping or prioritizing, use multiple executor services. You can instantiate more than one. You can have as many executor services as you want, provided you do not overload the demand on your deployment machine for CPU cores and memory (think about your maximum simultaneous usage).
ExecutorService esSingleThread = Executors.newSingleThreadExecutor() ;
ExecutorService esMultiThread = Executors.newCachedThreadPool() ;
One executor service might be backed by a single thread to limit the demands on the deployment computer, while others might be backed by a thread pool to get more work done. You can use these multiple executor services as your multiple queues. No need for you to be managing queues and workers as seen in the code of your Question. Executors were invented to further simplify working with multiple threads.
Concurrency
You said:
And I don't want to execute two tasks on the same file at the same time, so such tasks with the same paths should be performed sequentially.
You should have a better way to handle the concurrency conflict that just scheduling tasks on threads.
Java has ways to manage concurrent access to files. Search to learn more, as this has been covered on Stack Overflow already.
Perhaps I have not understood fully your needs, so do comment if I am off-base.
It seems that you need some sort of "Task Dispatcher" that executes or holds some tasks depending on some identifier (here the Path of the file the task is applied to).
You could use something like this :
public class Dispatcher<I> implements Runnable {
/**
* The executor used to execute the submitted task
*/
private final Executor executor;
/**
* Map of the pending tasks
*/
private final Map<I, Deque<Runnable>> pendingTasksById = new HashMap<>();
/**
* set containing the id that are currently executed
*/
private final Set<I> runningIds = new HashSet<>();
/**
* Action to be executed by the dispatcher
*/
private final BlockingDeque<Runnable> actionQueue = new LinkedBlockingDeque<>();
public Dispatcher(Executor executor) {
this.executor = executor;
}
/**
* Task in the same group will be executed sequentially (but not necessarily in the same thread)
* #param id the id of the group the task belong
* #param task the task to execute
*/
public void submitTask(I id, Runnable task) {
actionQueue.addLast(() -> {
if (canBeLaunchedDirectly(id)) {
executeTask(id, task);
} else {
addTaskToPendingTasks(id, task);
ifPossibleLaunchPendingTaskForId(id);
}
});
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
actionQueue.takeFirst().run();
} catch (InterruptedException e) {
Thread.currentThread().isInterrupted();
break;
}
}
}
private void addTaskToPendingTasks(I id, Runnable task) {
this.pendingTasksById.computeIfAbsent(id, i -> new LinkedList<>()).add(task);
}
/**
* #param id an id of a group
* #return true if a task of the group with the provided id is currently executed
*/
private boolean isRunning(I id) {
return runningIds.contains(id);
}
/**
* #param id an id of a group
* #return an optional containing the first pending task of the group,
* an empty optional if no such task is available
*/
private Optional<Runnable> getFirstPendingTask(I id) {
final Deque<Runnable> pendingTasks = pendingTasksById.get(id);
if (pendingTasks == null) {
return Optional.empty();
}
assert !pendingTasks.isEmpty();
final Runnable result = pendingTasks.removeFirst();
if (pendingTasks.isEmpty()) {
pendingTasksById.remove(id);
}
return Optional.of(result);
}
private boolean canBeLaunchedDirectly(I id) {
return !isRunning(id) && pendingTasksById.get(id) == null;
}
private void executeTask(I id, Runnable task) {
this.runningIds.add(id);
executor.execute(() -> {
try {
task.run();
} finally {
actionQueue.addLast(() -> {
runningIds.remove(id);
ifPossibleLaunchPendingTaskForId(id);
});
}
});
}
private void ifPossibleLaunchPendingTaskForId(I id) {
if (isRunning(id)) {
return;
}
getFirstPendingTask(id).ifPresent(r -> executeTask(id, r));
}
}
To use it, you need to launch it in a separated thread (or you can adapt it for a cleaner solution) like this :
final Dispatcher<Path> dispatcher = new Dispatcher<>(Executors.newCachedThreadPool());
new Thread(dispatcher).start();
dispatcher.submitTask(path, task1);
dispatcher.submitTask(path, task2);
This is basic example, you might need to keep the thread and even better wrap all of that in a class.
all you need is a hash map of actors, with file path as a key. Different actors would run in parallel, and concrete actor would handle tasks sequentially.
Your solution is wrong because Worker class uses blocking operation take but is executed in a limited thread pool, which may lead to a thread starvation (a kind of deadlock). Actors do not block when waiting for next message.
import org.df4j.core.dataflow.ClassicActor;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
public class TasksOrderingExecutor {
public static class Task implements Runnable {
private final String path;
private final String task;
public Task(String path, String task) {
this.path = path;
this.task = task;
}
//Task code here
String getPath() {
return path;
}
#Override
public void run() {
System.out.println(path+"/"+task+" started");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
System.out.println(path+"/"+task+" stopped");
}
}
static class Worker extends ClassicActor<Task> {
#Override
protected void runAction(Task task) throws Throwable {
task.run();
}
}
private final ExecutorService executorService;
private final Map<String,Worker> workers = new HashMap<String,Worker>(){
#Override
public Worker get(Object key) {
return super.computeIfAbsent((String) key, (k) -> {
Worker res = new Worker();
res.setExecutor(executorService);
res.start();
return res;
});
}
};
/**
* #param queuesNr nr of concurrent task queues
*/
public TasksOrderingExecutor(int queuesNr) {
executorService = ForkJoinPool.commonPool();
}
public void submit(Task task) {
Worker worker = getWorker(task);
worker.onNext(task);
}
public void stop() throws InterruptedException {
for (Worker w : workers.values()) {
w.onComplete();
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
}
private Worker getWorker(Task task) {
//check here if a runnig worker with a specific path exists? If yes return it, else return a free worker. How do I check if a worker is currently running?
return workers.get(task.getPath());
}
public static void main(String[] args) throws InterruptedException {
TasksOrderingExecutor orderingExecutor = new TasksOrderingExecutor(20);
orderingExecutor.submit(new Task("path1", "task1"));
orderingExecutor.submit(new Task("path1", "task2"));
orderingExecutor.submit(new Task("path2", "task1"));
orderingExecutor.submit(new Task("path3", "task1"));
orderingExecutor.submit(new Task("path2", "task2"));
orderingExecutor.stop();
}
}
The protocol of execution shows that tasks with te same key are executed sequentially and tasks with different keys are executed in parallel:
path3/task1 started
path2/task1 started
path1/task1 started
path3/task1 stopped
path2/task1 stopped
path1/task1 stopped
path2/task2 started
path1/task2 started
path2/task2 stopped
path1/task2 stopped
I used my own actor library DF4J, but any other actor library can be used.

Tomcat thread count gets increased only

I have created simple web application with JSP-Servlet hosted on Tomcat 7. As per my requirement, I need to create 2 background threads which will keep checking their respective shared Queues with some time duration and if it find any element in their respective queues it will process that element.
For this 2 continuous thread management, I have used java.util.concurrent.Executors. It works fine for me but the issue is, java.lang.Thread.activeCount() gets incremented only when I do some operation to add elements in resource queues. Also when I check with Java VisualVM, it shows the thread count increased continuously.
Following are my code segments:
Web.xml:
<servlet>
<servlet-name>InvokerServlet</servlet-name>
<display-name>InvokerServlet</display-name>
<description></description>
<servlet-class>com.test.servlet.InvokerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
This is startup my InvokerServlet at the time of tomcat start, which will initiate the threads:
InvokerServlet.java:
public class InvokerServlet extends HttpServlet {
Logger log = Logger.getLogger(InvokerServlet.class);
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public InvokerServlet() {
super();
log.debug("Initiate thread invoking");
new ThreadInvoker().invokeThreads();
}
...
...
}
ThreadInvoker.java:
public class ThreadInvoker
{
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
public static Queue queue1 = new LinkedBlockingQueue();
public static Queue queue2 = new LinkedBlockingQueue();
private static ExecutorService executor = null;
private static volatile Future result1= null;
private static volatile Future result2 = null;
public void invokeThreads()
{
executor = Executors.newFixedThreadPool(2);
while (true)
{
System.out.println("----> " + java.lang.Thread.activeCount());
try
{
checkTasks();
Thread.sleep(1000);
} catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
}
}
}
private void checkTasks() throws Exception
{
if(queue1.size() > 0)
{
result1 = executor.submit(t1);
}
if(queue2.size() > 0)
{
result2 = executor.submit(t2);
}
}
}
Thread1.java
public class Thread1 implements Runnable
{
public void run()
{
try
{
log.debug("Inside Thread1 run");
Thread.sleep(2000);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Thread2.java
public class Thread2 implements Runnable
{
public void run()
{
try
{
log.debug("Inside Thread2 run");
Thread.sleep(2000);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
So my problem is why the Active thread count gets incremented when I add element in queue1 and queue2 with some external operation. Why it does not gets decremented once their respective thread gets completed their work?
Please let me know when I am doing wrong.
I hope you're experimenting and that's not the entire code. From your code InvokerServlet will never finish because the constructor goes on to an endless while loop. Because, new ThreadInvoker().invokeThreads() will never finish.
If you wanted to see the thread count of just the executor, you should use this, and the count will not increase beyond 2 as you have configured.
System.out.println("----> " + ((ThreadPoolExecutor)executor).getActiveCount());
I hope the increasing number of threads are not executor threads but the threads which are dropping elements into the queue. If you take a thread dump, you'll know what those threads are doing and on whom are they waiting. That will give you an answer, why those threads are increasing.
You are not dequeueing from the queues - but, that shouldn't block you now. It can go until you add elements of the count Integer.MAX_VALUE
You're creating a thread leak in your ThreadInvoker class by creating new Threads t1 and t2. You never start them, so they can't die.
You're also going to an infinite loop in your InvokerServlet constructor.
My recommendation: scrap all your code and look for a proper tutorial on servlet container background tasks. You're not the first one to want to observe a few queues.

Thread Template

OK so I have a GUI Java application that permits the user to select and launch between 5-500 software devices each represented by a Thread. The Threads continuously update the GUI with information.
The user can select threads and pause, resume or kill them.
All the information on threads and thread pools, interrupts, Future.... I just got lost and wanted to set fire to the internet =)
What I need is some clear guidance on the standard way forward for this. I have below the outline of my thread class here.
Is this a good template to start with ? If not please edit.
package ACsimForm;
import java.util.Random;
import javax.swing.SwingUtilities;
public class Squeak implements Runnable {
private String name = "";
private javax.swing.JTextArea ScroolPage;
Squeak (String name, javax.swing.JTextArea MW )
{
this.value = true;
this.name = name;
this.ScroolPage = MW;
}
Random r = new Random();
int num = r.nextInt(10-1) + 1;
#Override
public void run ()
{
updateGUI("Thread "+name+" Loaded and Running");
while(true)
{
updateGUI("New Data");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
updateGUI("Thread "+name+" Exiting!");
//return exits the method killing the thread
return;
}
}
}
//this is the new way to communicate back to the GUI
private void updateGUI(final String foo) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ScroolPage.append(foo+"\r\n");
}
});
}
}
What is the best way to keep tack of up 500 threads in a way that permits you to kill or pause/resume them from the GUI?
Many Thanks.
I think your Runnable is almost there. Abandon the idea of a magic Boolean flag - this is plagued with issues (read up on volatile). Use the interrupt itself as a signal. This is why it's there!
Here is a simple example of a system with an arbitrary number of Threads:
private static final class Printer implements Runnable {
private final String printMe;
public Printer(String printMe) {
this.printMe = printMe;
}
#Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + "says: " + printMe);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException ex) {
return;
}
}
}
}
public static void main(String[] args) throws Exception {
final ExecutorService executorService = Executors.newCachedThreadPool();
final Map<Integer, Future<?>> futures = new HashMap<>();
for (int i = 0; i < 10; ++i) {
futures.put(i, executorService.submit(new Printer("Printer" + i)));
}
final Scanner scanner = new Scanner(System.in);
while (true) {
final String input = scanner.nextLine();
if ("EXIT".equalsIgnoreCase(input)) {
break;
}
final Integer threadToStop;
try {
threadToStop = Integer.parseInt(input);
} catch (NumberFormatException ex) {
System.out.println("Not a number");
continue;
}
final Future<?> f = futures.remove(threadToStop);
if (f == null) {
System.out.println("Not a valid thread");
continue;
}
f.cancel(true);
}
executorService.shutdownNow();
}
We use an ExecutorService to manage the Threads - you should never use Threads directly, this is again plagued with land mines.
The ExecutorService is asked to run an arbitrary number of tasks - you can see how to add tasks in the for loop.
Then ExecutorService returns a Future for each task added - these are handles to the tasks. They allow us to check if they are still going/done or have encountered an error.
We Map the Futures to task names and than allow the user to selectively kill tasks from input.
You cannot "pause" and "resume" a Thread (well you can, but you are better off not worrying about that). You simply cancel a task when you want it paused and then reissue it to restart it. The good thing is that the ExecutorService will recycle the Thread that the task was running on so you won't loose performance.
If you are issuing commands to the Map of Futures from multiple threads you would need a ConcurrentHashMap.
A common pitfall is assuming that your application will exit cleanly with the ExecutorService running. This is not the case. The ExecutorService spawns non-daemon threads and so the application cannot exit until they are all done. You have two options; the first is a bit hacky - just give the ExecutorService your own ThreadFactory and make the Threads daemon, the second is to shutdown the ExecutorService when you are done with it as I have in the example.
This is not a complete answer but a few tips to get things done.
You should use an ExecutorService for your threads, and .submit() them. In order to register them and have them available, say by name, create a Map<String, Future<?>>.
Some pseudo code, could be improved:
#GuardedBy("this") // see JSR 305
final Map<String, Future<?>> allSqueaks
= new HashMap<String, Future<?>>();
final ExecutorService service
= Executors.newCachedThreadPool();
// Registering:
public synchronized void registerSqueak(final Squeak squeak)
{
allSqueaks.put(squeak.getName(), service.submit(squeak));
}
// Cancelling:
public synchronized void cancelSqueakByName(final String name)
{
// Note: deal with non existing name if it can happen
final Future<?> victim = allSqueaks.remove(name);
victim.cancel(true);
}

Why does ExecutorService keep executing when threads are blocking?

I am trying to write a part of a multithreaded program where each thread from a fixed thread pool tries to fetch an object from a Queue and if the Queue is empty the thread waits.
The problem I am experiencing is that the memory used by the program keeps increasing.
public class Ex3 {
public static LinkedBlockingQueue<Integer> myLBQ = new LinkedBlockingQueue<Integer>(10);
public static void main(String argc[]) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(3);
myLBQ.add(new Integer(1));
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
}
}
class MyHandler implements Runnable {
LinkedBlockingQueue<Integer> myLBQ;
MyHandler(LinkedBlockingQueue<Integer> myLBQ) {
this.myLBQ = myLBQ;
}
public void run() {
try {
myLBQ.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I don't understand why the executor.execute keeps firing when the threads should be waiting for an item to be added to the Queue. How do I modify my code to reflect this?
This adds tasks to the executor as fast as it can.
for (;;) {
executor.execute(new MyHandler(myLBQ));
}
This will consume about 200 MB per second. It doesn't have anything to do with whether there are tasks to perform or not.
If you don't want to do this I suggest you move the loop to the runnable and add only one. This will cause it to wait for tasks forever.
A better approach is to use the ExecutorService's builtin queue to queue tasks.
ExecutorService executor = Executors.newFixedThreadPool(3);
final int taskId = 1;
executor.submit(new Runnable() {
#Override
public void run() {
doSomething(taskId);
}
});
executor.shutdown();
This does the same thing, but is much simpler IMHO.
it's because you're creating a gazillion instances of MyHandler and inserting them in the internal queue of the executor.
That infinite for loop is quite mean.

Categories