I am using a ThreadPoolExecutor to execute tasks in my Java application. I have a requirement where I want to get the number of active tasks in the queue at any point in time in the executor queue . I looked up at the javadoc for ThreadPoolExecutor and found two relevant methods: getTaskCount() and getCompletedTaskCount().
Per the documentation, I could get the number of scheduled tasks and completed tasks from the above two methods respectively. But I am not able to find a solution for getting the number of active tasks in the queue at any point in time. I can do something like:
getTaskCount() = getCompletedTaskCount() + failed tasks + active tasks
But the number of failed tasks is not directly available to arrive at the intended calculation.
Am I missing something here ?
I don't think you need to know the failed count with the calculation you're trying to use.
long submitted = executor.getTaskCount();
long completed = executor.getCompletedTaskCount();
long notCompleted = submitted - completed; // approximate
Would be (approximately) sufficient.
Alternatively, you can use getQueue() with size():
int queued = executor.getQueue().size();
int active = executor.getActiveCount();
int notCompleted = queued + active; // approximate
This answer presumes you're looking for a "not yet completed" count. Your question contradicts itself so I'm not completely certain what you're asking. Reply to my comment on your question if this is incorrect, and I'll update this answer accordingly.
Have you tried using the beforeExecute and afterExecute methods? These are called before and after a task is executed. The after execute method even supplies a throwable as a second argument, so you know when a task has failed.
You could add a hook so that beforeExecute increments the value of the active tasks, and afterExecute decrements it. Ofcourse, these methods are called on their respective fields, so that you would have to synchronize the result on a mutual lock Object.
To use these methods, just override the ThreadPoolExecutor object of your choice and add the hook there.
For instance, the following code should hopefully work:
public class MyExecutor extends ThreadPoolExecutor {
//Lock object used for synchronization
private final Object lockObject = new Object();
//Contains the active task count
private int activeTaskCount = 0;
//Failed task count
private int failedTaskCount = 0;
private int succeededTaskCount = 0;
public MyExecutor () {
//call super here with your parameters;
}
public int getActiveTaskCount(){
synchronized(lockObject){
return activeTaskCount;
}
}
public int getFailedTaskCount(){
synchronized(lockObject){
return failedTaskCount ;
}
}
public int getSucceededTaskCount(){
synchronized(lockObject){
return succeededTaskCount ;
}
}
protected void beforeExecute(Thread t,
Runnable r){
super.beforeExecute(t,r);
synchronized(lockObject){
activeTaskCount++;
}
}
protected void afterExecute(Runnable r,Throwable t){
super.afterExecute(r,t);
synchronized(lockObject){
activeTaskCount--;
if(t!=null){
failedTaskCount++;
}else{
succeededTaskCount++;
}
}
}
}
Related
In a non-JavaFX application I would like to have the same Class like Task.
A Thread which executes something and is able to return its progress.
Is there something that could perform a task similar to the above mentioned?
The Task class adds a bunch of functionality to a FutureTask, but all of the non-obvious parts are to do with providing observable properties and ensuring they are updated on the FX Application Thread. It sounds like you don't need any of the difficult parts: you are querying the task to check its progress (so you don't need observability, i.e. callbacks to be invoked when the progress changes) and you don't have an FX Application Thread on which to schedule updates.
So, for example, if you want to track progress, just add the appropriate property to your Callable implementation. If you want the progress to be accessible from multiple threads, use an atomic reference to represent the progress internally (or at least make it volatile):
import java.util.concurrent.Callable ;
import java.util.concurrent.atomic.AtomicLong ;
public class MyCountingTask implements Callable<Void> {
private AtomicLong progressCount = new AtomicLong();
private final long max = 1000 ;
#Override
public Void call() throws InterruptedException {
for (int count = 0; count < max ; count++) {
progressCount.set(count);
// in real life, do actual work instead of sleeping...
Thread.sleep(100);
}
progressCount.set(max);
return null ;
}
public double getProgress() {
return 1.0*progressCount.get() / max ;
}
}
So in Java concurrency, there is the concept of a task which is really any implementing Runnable or Callable (and, more specifically, the overridden run() or call() method of that interface).
I'm having a tough time understanding the relationship between:
A task (Runnable/Callable); and
An ExecutorService the task is submitted to; and
An underlying, concurrent work queue or list structure used by the ExecutorService
I believe the relationship is something of the following:
You, the developer, must select which ExecutorService and work structure best suits the task at hand
You initialize the ExecutorService (say, as a ScheduledThreadPool) with the underlying structure to use (say, an ArrayBlockingQueue) (if so, how?!?!)
You submit your task to the ExecutorService which then uses its threading/pooling strategy to populate the given structure (ABQ or otherwise) with copies of the task
Each spawned/pooled thread now pulls copies of the task off of the work structure and executes it
First off, please correct/clarify any of the above assumptions if I am off-base on any of them!
Second, if the task is simply copied/replicated over and over again inside the underlying work structure (e.g., identical copies in each index of a list), then how do you ever decompose a big problem down into smaller (concurrent) ones? In other words, if the task simply does steps A - Z, and you have an ABQ with 1,000 of those tasks, then won't each thread just do A - Z as well? How do you say "some threads should work on A - G, while other threads should work on H, and yet other threads should work on I - Z", etc.?
For this second one I might need a code example to visualize how it all comes together. Thanks in advance.
Your last assumption is not quite right. The ExecutorService does not pull copies of the task. The program must supply all tasks individually to be performed by the ExecutorService. When a task has finished, the next task in the queue is executed.
An ExecutorService is an interface for working with a thread pool. You generally have multiple tasks to be executed on the pool, and each operates on a different part of the problem. As the developer, you must specify which parts of the problem each task should work on when creating it, before sending it to the ExecutorService. The results of each task (assuming they are working on a common problem) should be added to a BlockingQueue or other concurrent collection, where another thread may use the results or wait for all tasks to finish.
Here is an article you may want to read about how to use an ExecutorService: http://www.vogella.com/articles/JavaConcurrency/article.html#threadpools
Update: A common use of the ExecutorService is to implement the producer/consumer pattern. Here is an example I quickly threw together to get you started--it is intended for demonstration purposes only, as some details and concerns have been omitted for simplicity. The thread pool contains multiple producer threads and one consumer thread. The job being performed is to sum the numbers from 0...N. Each producer thread sums a smaller interval of numbers, and publishes the result to the BlockingQueue. The consumer thread processes each result added to the BlockingQueue.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NumberCounter {
private final ExecutorService pool = Executors.newFixedThreadPool(2);
private final BlockingQueue<Integer> queue = new ArrayBlockingQueue(100);
public void startCounter(int max, int workers) {
// Create multiple tasks to add numbers. Each task submits the result
// to the queue.
int increment = max / workers;
for (int worker = 0; worker < workers; worker++) {
Runnable task = createProducer(worker * increment, (worker + 1) * increment);
pool.execute(task);
}
// Create one more task that will consume the numbers, adding them up
// and printing the results.
pool.execute(new Runnable() {
#Override
public void run() {
int sum = 0;
while (true) {
try {
Integer result = queue.take();
sum += result;
System.out.println("New sum is " + sum);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
private Runnable createProducer(final int start, final int stop) {
return new Runnable() {
#Override
public void run() {
System.out.println("Worker started counting from " + start + " to " + stop);
int count = 0;
for (int i = start; i < stop; i++) {
count += i;
}
queue.add(count);
}
};
}
public static void main(String[] args) throws InterruptedException {
NumberCounter counter = new NumberCounter();
counter.startCounter(10000, 5);
}
}
There's something odd about the implementation of the BoundedExecutor in the book Java Concurrency in Practice.
It's supposed to throttle task submission to the Executor by blocking the submitting thread when there are enough threads either queued or running in the Executor.
This is the implementation (after adding the missing rethrow in the catch clause):
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command) throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
#Override public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
When I instantiate the BoundedExecutor with an Executors.newCachedThreadPool() and a bound of 4, I would expect the number of threads instantiated by the cached thread pool to never exceed 4. In practice, however, it does. I've gotten this little test program to create as much as 11 threads:
public static void main(String[] args) throws Exception {
class CountingThreadFactory implements ThreadFactory {
int count;
#Override public Thread newThread(Runnable r) {
++count;
return new Thread(r);
}
}
List<Integer> counts = new ArrayList<Integer>();
for (int n = 0; n < 100; ++n) {
CountingThreadFactory countingThreadFactory = new CountingThreadFactory();
ExecutorService exec = Executors.newCachedThreadPool(countingThreadFactory);
try {
BoundedExecutor be = new BoundedExecutor(exec, 4);
for (int i = 0; i < 20000; ++i) {
be.submitTask(new Runnable() {
#Override public void run() {}
});
}
} finally {
exec.shutdown();
}
counts.add(countingThreadFactory.count);
}
System.out.println(Collections.max(counts));
}
I think there's a tiny little time frame between the release of the semaphore and the task ending, where another thread can aquire a permit and submit a task while the releasing thread hasn't finished yet. In other words, it has a race condition.
Can someone confirm this?
BoundedExecutor was indeed intended as an illustration of how to throttle task submission, not as a way to place a bound on thread pool size. There are more direct ways to achieve the latter, as at least one comment pointed out.
But the other answers don't mention the text in the book that says to use an unbounded queue and to
set the bound on the semaphore to be equal to the pool size plus the
number of queued tasks you want to allow, since the semaphore is
bounding the number of tasks both currently executing and awaiting
execution. [JCiP, end of section 8.3.3]
By mentioning unbounded queues and pool size, we were implying (apparently not very clearly) the use of a thread pool of bounded size.
What has always bothered me about BoundedExecutor, however, is that it doesn't implement the ExecutorService interface. A modern way to achieve similar functionality and still implement the standard interfaces would be to use Guava's listeningDecorator method and ForwardingListeningExecutorService class.
You are correct in your analysis of the race condition. There is no synchronization guarantees between the ExecutorService & the Semaphore.
However, I do not know if throttling the number of threads is what the BoundedExecutor is used for. I think it is more for throttling the number of tasks submitted to the service. Imagine if you have 5 million tasks that need to submit, and if you submit more then 10,000 of them you run out of memory.
Well you only will ever have 4 threads running at any given time, why would you want to try and queue up all 5 millions tasks? You can use a construct similar to this to throttle the number of tasks queued up at any given time. What you should get out of this is that at any given time there are only 4 tasks running.
Obviously the resolution to this is to use a Executors.newFixedThreadPool(4).
I see as much as 9 threads created at once. I suspect there is a race condition which causes there to be more thread than required.
This could be because there is before and after running the task work to be done. This means that even though there is only 4 thread inside your block of code, there is a number of thread stopping a previous task or getting ready to start a new task.
i.e. the thread does a release() while it is still running. Even though its the last thing you do its not the last thing it does before acquiring a new task.
I am trying to learn the java concurrency API, and for my exercise i want to schedule a job to run periodically every X seconds. The job will compute a random number.
I want to get the result of the scheduled task as soon as it is finished.
I could not get this done only with the API so i hacked it.
Is there a way to do this better, without using low level mechanisms?
I would like to be able to remove the synchronization in MyRandomGiverTask.getResult() and instead use
something like the ScheduledFuture.get(). But in my code ScheduledFuture is never done/completed.
This is my current solution:
class A {
public static void main() {
MyRandomGiverTask task = new MyRandomGiverTask(200);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
ScheduledFuture<Double> scheduledDouble =
(ScheduledFuture<Double>) scheduler
.scheduleAtFixedRate(task, 1, 4, TimeUnit.SECONDS);
while (true) {
System.out.println(" >> " + task.getResult());
}
}
public class MyRandomGiverTask implements Runnable {
MyRandomGiver giver = new MyRandomGiver();
int param;
double result;
public MyRandomGiverTask(int param) { this.param = param; }
#Override public void run() { result = giver.getRandom(param); }
public double getResult() {
try {
while (result == 0d) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
} finally {
result = 0d;
}
}
}
}
Your task is scheduled at fixed rate. This means that until you cancel the task, it will be executed again and again by the executor with a fixed rate. The only thing that such a task can do is to have a side-effect. It can't return anything, since the future that is returned by the executor represents all the pending executions of the task. BTW, you'll notice that the schedule method takes a Callable as argument (which can result something), whereas the sceduleAtFixedRate method only takes a Runnable as argument (which returns void, thus can't return anything).
So, if you want to print the result of each execution, then simply make the task itself (the Runnable) print its result, or have the runnable put its result in a blocking queue, and have the main thread take from the queue. The main thread will thus be blocked untile some result is put in the queue.
If you want to get every random number computed, use a BlockingQueue. the scheduled tasks put()s new random numbers in the queue and whatever wants them can take() them.
also, if you were going to use something like your solution, you would want to use wait()/notify(), not sleep().
I have Callable object executed using ExecutorService.
How to return interim results from this callable?
I know there is javax.swing.SwingWorker#publish(results) for Swing but I don't use Swing.
There are a couple of ways of doing this. You could do it with a callback or you could do it with a queue.
Here's an example of doing it with a callback:
public static interface Callback<T> {
public void on(T event);
}
Then, an implementation of the callback that does something with your in progress events:
final Callback<String> callback = new Callback<String>() {
public void on(String event) {
System.out.println(event);
}
};
Now you can use the callback in your pool:
Future<String> submit = pool.submit(new Callable<String>() {
public String call() throws Exception {
for(int i = 0; i < 10; i++) {
callback.on("process " + i);
}
return "done";
}
});
It is not clear what an "interim result" really is. The interfaces used in the concurrency package simply do not define this, but assume methods that resemble more or less pure functions.
Hence, instead this:
interim = compute something
finalresult = compute something else
do something like this:
interim = compute something
final1 = new Pair( interim, fork(new Future() { compute something else }) )
(Pseudocode, thought to convey the idea, not compileable code)
EDIT The idea is: instead of running a single monolithic block of computations (that happens to reach a state where some "interim results" are available) break it up so that the first task returns the former "interim" result and, at the same time, forks a second task that computes the final result. Of course, a handle to this task must be delivered to the caller so that it eventually can get the final result. Usually, this is done with the Future interface.
You can pass, let's say, an AtomicInteger to your class (the one that will be submitted by the executor) inside that class you increment it's value and from the calling thread you check it's value
Something like this:
public class LongComputation {
private AtomicInteger progress = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException,
ExecutionException {
AtomicInteger progress = new AtomicInteger(0);
LongComputation computation = new LongComputation(progress);
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> result = executor.submit(() -> computation.compute());
executor.shutdown();
while (!result.isDone()) {
System.out.printf("Progress...%d%%%n", progress.intValue());
TimeUnit.MILLISECONDS.sleep(100);
}
System.out.printf("Result=%d%n", result.get());
}
public LongComputation(AtomicInteger progress) {
this.progress = progress;
}
public int compute() throws InterruptedException {
for (int i = 0; i < 100; i++) {
TimeUnit.MILLISECONDS.sleep(100);
progress.incrementAndGet();
}
return 1_000_000;
}
}
What you're looking for is java.util.concurrent.Future.
A Future represents the result of an asynchronous computation. Methods
are provided to check if the computation is complete, to wait for its
completion, and to retrieve the result of the computation. The result
can only be retrieved using method get when the computation has
completed, blocking if necessary until it is ready. Cancellation is
performed by the cancel method. Additional methods are provided to
determine if the task completed normally or was cancelled. Once a
computation has completed, the computation cannot be cancelled. If you
would like to use a Future for the sake of cancellability but not
provide a usable result, you can declare types of the form Future
and return null as a result of the underlying task.
You would have to roll your own API with something like Observer/Observerable if you want to publish intermediate results as a push. A simpler thing would be to just poll for current state through some self defined method.