Join a group of threads with overall timeout - java

Is there a way to join a group of threads simultaneously with an overall timeout?
Suppose we have Collection<Thread> threads; and int timeout;. If I didn't care about the timeout, I would do
for (Thread t : threads)
t.join();
but I want to wait until either all threads are done, or a certain amount of time passes, whichever comes first. I was searching for a (hypothetical) ThreadGroup.join(int) which would do this.
Note that what I'm asking for is different from doing
for (Thread t : threads)
t.join(timeout);
Rather, I'm looking for something less verbose (and perhaps more reliable) than
int timeout = 10000;
for (Thread t : threads) {
if (timeout <= 0) break;
long start = System.currentTimeMillis();
t.join(timeout);
long end = System.currentTimeMillis();
// substract time elapsed from next timeout:
timeout -= (int) (end - start);
}

First create a single CountDownLatch having a count for every thread in the group.
A controlling thread can await(timeout, TimeUnit) on the latch.
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html#await-long-java.util.concurrent.TimeUnit-
Start the threads that are in the group.
Each of the threads in the group should decrement the latch when it completes.
The controlling thread will wait until everything in the group has completed or the timeout happens, and because await returns a boolean, the controlling thread can tell whether the latch was decremented naturally or whether a timeout occurred.

Related

Amount of Threads with subtasks

An optimum of threads in a pool is something that is case specific, though there is a rule of thumb which says #threads = #CPU +1.
However, how does this work with threads spanning other threads and waiting (i.e. blocked until thread.join() is successful) for these 'subthreads'?
Assume that I have code that requires the execution of list of tasks (2), which has subtasks(2), which has subsubtasks(3) and so on. The total number of tasks is 2*2*3 = 12, though 18 threads will be created (because a threads will 'spawn' more subtasks (threads), where the thread spawning more threads will be blocked untill all is over. See below for pseudo code.
I am assuming that for a CPU with N cores there is a rule of thumb that everything can be parallelized if the highest number of active threads (12) is #CPU + 1. Is this correct?
PseudoCode
outputOfTask = []
for subtask in SubTaskList
outputOfTask --> append(subtask.doCompute())
// wait untill all output is finished.
in subtask.java:
Each subtask, for example, implements the same interface, but can be different.
outputOfSubtask = []
for task in subsubTaskList
// do some magic depending on the type of subtask
outputOfSubtask -> append( task.doCompute())
return outputOfSubtask
in subsubtask.java:
outputOfSubsubtask = []
for task in subsubsubtask
// do some magic depending on the type of subsubtask
outputOfSubsubtask -> append( task.doCompute())
return outputOfSubsubtask
EDIT:
Dummy code Java code. I used this in my original question to check how many threads were active, but I assume that the pseudocode is more clear. Please note: I used the Eclipse Collection, this introduces the asParallel function which allows for a shorter notation of the code.
#Test
public void testasParallelthreads() {
// // ExecutorService executor = Executors.newWorkStealingPool();
ExecutorService executor = Executors.newCachedThreadPool();
MutableList<Double> myMainTask = Lists.mutable.with(1.0, 2.0);
MutableList<Double> mySubTask = Lists.mutable.with(1.0, 2.0);
MutableList<Double> mySubSubTask = Lists.mutable.with(1.0, 2.0);
MutableList<Double> mySubSubSubTask = Lists.mutable.with(1.0, 2.0, 2.0);
MutableList<Double> a = myMainTask.asParallel(executor, 1)
.flatCollect(task -> mySubTask.asParallel(executor,1)
.flatCollect(subTask -> mySubSubTask.asParallel(executor, 1)
.flatCollect(subsubTask -> mySubSubSubTask.asParallel(executor, 1)
.flatCollect(subsubTask -> dummyFunction(task, subTask, subsubTask, subsubTask,executor))
.toList()).toList()).toList()).toList();
System.out.println("pool size: " + ((ThreadPoolExecutor) executor).getPoolSize());
executor.shutdownNow();
}
private MutableList<Double> dummyFunction(double a, double b, double c, double d, ExecutorService ex) {
System.out.println("ThreadId: " + Thread.currentThread().getId());
System.out.println("Active threads size: " + ((ThreadPoolExecutor) ex).getActiveCount());
return Lists.mutable.with(a,b,c,d);
}
I am assuming that for a CPU with N cores there is a rule of thumb that everything can be parallelized if the highest number of active threads (12) is #CPU + 1. Is this correct?
This topic is extremely hard to generalize about. Even with the actual code, the performance of your application is going to be very difficult to determine. Even if you could come up an estimation, the actual performance may vary wildly between runs – especially considering that the threads are interacting with each other. The only time we can take the #CPU + 1 number is if the jobs that are submitted into the thread-pool are independent and completely CPU bound.
I'd recommend trying a number of different thread-pool size values under simulated load to find the optimal values for your application. Examining the overall throughput numbers or system load stats should give you the feedback you need.
However, how does this work with threads spanning other threads and waiting (i.e. blocked until thread.join() is successful) for these 'subthreads'?
Threads will block, and it is up to the os/jvm to schedule another one if possible. If you have a single thread pool executor and call join from one of your tasks, the other task won't even get started. With executors that use more threads, then the blocking task will block a single thread and the os/jvm is free to scheduled other threads.
These blocked threads should not consume CPU time, because they are blocked. So I am assuming that for a CPU with N cores there is a rule of thumb that everything can be parallelized if the highest number of active threads (24) is #CPU + 1. Is this correct?
Active threads can be blocking. I think you're mixing terms here, #CPU, the number of cores, and the number of virtual cores. If you have N physical cores, then you can run N cpu bound tasks in parallel. When you have other types of blocking or very short lived tasks, then you can have more parallel tasks.

How can I measure thread waiting time?

I couldn't find out how to measure the time that a Thread is waiting locked. I have to determine if a Thread is waiting locked more than 1 second and if so to run another Thread instead. Thanks!
Try this:
long startTime = System.nanoTime();
methodToTime();
long endTime = System.nanoTime();
long duration = endTime - startTime;
Time it using Sytem.nanoTime(); just before and after the wait.
long start = System.nanoTime();
wait();
long time = System.nanoTime() - start; // nanos
Or:
long start = System.nanoTime();
synchronized (objHere)
{
long time = System.nanoTime() - start; // nanos
// ...
}
Note: If a Thread is locked, the scheduler will continue with other Threads. You don't have to do this manually. That is the idea of threads. Maybe you are facing a deadlock? Wikipedia says it nicely:
A deadlock is a situation in which two or more competing actions are each waiting for the other to finish, and thus neither ever does.
Generally the methods which operates on locks accepts timeout as an argument. If you are using wait(), you can specify the amount of time by passing time to wait as argument. Check here for more details: http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait%28long%29.
If you are using Lock, then try tryLock method of it which accepts time it has to wait. Check this tutorial for an idea: http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

Complexity of the notifyAll operation

I don't understand the following fragment of the Java Concurrency in Practice book:
Using notifyAll when only one thread can make progress is inefficient - sometimes a little, sometimes grossly so. If ten threads are waiting on a condition queue, calling notifyAll causes each of them to wake up and contend for the lock; then most or all of them will go right back to sleep. This means a lot of context switches and a lot of contended lock acquisitions for each event that enables (maybe) a single thread to make progress. (In the worst case, using notifyAll results in O(n2) wakeups where n would suffice.)
An example code is in listing 14.6:
#ThreadSafe
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {
// CONDITION PREDICATE: not-full (!isFull())
// CONDITION PREDICATE: not-empty (!isEmpty())
public BoundedBuffer(int size) { super(size); }
// BLOCKS-UNTIL: not-full
public synchronized void put(V v) throws InterruptedException {
while (isFull())
wait();
doPut(v);
notifyAll();
}
// BLOCKS-UNTIL: not-empty
public synchronized V take() throws InterruptedException {
while (isEmpty())
wait();
V v = doTake();
notifyAll();
return v;
}
}
We can have, for example, the following sequence of events:
two consumer threads try to get an object from the buffer, the buffer is empty, so they are suspended.
10 producers put 10 objects to the buffer, the buffer capacity is 10.
100001 producers try to put 100001 objects to the buffer, the buffer is full, so they are suspended.
first consumer gets an object from the buffer and invokes notifyAll.
a producer puts an object to the buffer and invokes notifyAll, the buffer is full.
Now only one thread can make progress - the consumer thread. We also have 100000 producers, who can't make progress.
I don't understand why in the worst case there will be O(n2) wakeups, before the thread which can make progress is woken up.
I think the worst case is the following sequence
All threads are woken up (because of notifyAll). We "used" O(n) wakeups.
A producer thread gets the lock, other threads are suspended. The producer thread can't make progress, so it is suspended and it releases the lock.
Now only one producer thread is woken up, because a different mechanism is used (a thread resumes execution, because it gets the lock - but this time the notifyAll is not called). We "use" only O(1) wakeups.
The second producer can't make progress, so it is suspended and it releases the lock.
Similar events happen for all other waiting producers.
Finally the thread which can make progress (the consumer thread) is woken up.
I think we "used" O(n) + O(n)*O(1) = O(n) wakeups.
Is there an error in the book, or am I missing something here?
Something gets put into the queue n times. "n wakeups would suffice" means that ideally we'd like one consumer to be notified when a producer drops something into the buffer, for instance, so there would be n notifications, and even better they would all be uncontended. But instead all of the threads waiting on the lock, including all the producers (minus 1, the one doing the putting) and all the consumers (the ones who are waiting anyway), get notified every time something gets dropped in the queue, they all fight for the lock and the scheduler picks a winner. (And we're not even considering the case where the chosen thread has to wait, that's just a detail.) So there are n times that notifyAll gets called, once for each put, and each notifyAll wakes up multiple producers and multiple consumers, which is where they get O(n2) wakeups.
Let’s we have n consumer and n producer threads and the buffer is empty(example with full buffer is similar). All threads are in ready to run state(scheduler may chose any to run).
If any consumer run - it will go to waiting state. If any producer run - it will succeed and invoke notifyAll().
Case that maximize quantity of wait() call(and wakeups):
Example for 5 producer and 5 consumer
+--------------+-------------------------------------+
| C-C-C-C-C-P | all consumers move to waiting state |
+--------------+-------------------------------------+
| C*-C-C-C-C-P | 5 wake ups |
+--------------+-------------------------------------+
| C*-C-C-C-P | 4 wake ups |
+--------------+-------------------------------------+
| C*-C-C-P | 3 wake ups |
+--------------+-------------------------------------+
| C*-C-P | 2 wake ups |
+--------------+-------------------------------------+
| C* | 1 wake up |
+--------------+-------------------------------------+
P - producer
C - consumer
C* - consumer that succesfully finish take() method ( without wait() invoking)
Let’s count:
5 + 4 + 3 + 2 + 1 = 15
For n producer and n consumer:
n + (n-1) + (n-2) + (n-3) + … + 1 = 1 + 2 + 3 + 4 + ...+ n = sum of first n elements of arithmetic progression =
n * (1 + n) /2 = (n + n^2) / 2 → O(n^2)

FixedThreadPool

What I need to do is use a FixedThreadPool of size 3 and then use it to print the ThreadName and then make it go to sleep for a random amount of time within a specified time interval and print that it is awake when it is done. I need to do it thread by thread but my output is coming with all the 3 threads together.
Desired output:
pool-1-thread-1 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-1 done sleeping
pool-1-thread-2 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-2 done sleeping
pool-1-thread-3 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-3 done sleeping
I need to use FixedThreadPool only
import java.util.Random;
import java.util.concurrent.*;
class Sleep implements Runnable
{
public void run()
{
Random ran = new Random();
int randomnumber = ran.nextInt(1000-800+1)+800;
System.out.print(Thread.currentThread().getName()+" ");
System.out.println("Going to sleep for random amount of time interval between 800 ms and 1000ms");
try
{
Thread.sleep(randomnumber);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" done sleeping");
Thread.yield();
}
}
public class Ch6Ex3
{
public static void main(String[] args)
{
ExecutorService exe = Executors.newFixedThreadPool(3);
for(int i=0;i<3;i++)
{
exe.execute(new Sleep());
}
exe.shutdown();
}
}
Create thread pool with only 1 thread. If you use 3 threads then up to 3 runnable can be run concurrently and it's not what you want. So use:
ExecutorService exe = Executors.newFixedThreadPool(1);
Actually better option will be to use newSingleThreadExecutor because it explicitly shows that it runs only 1 runnable at any given time:
ExecutorService exe = Executors.newSingleThreadExecutor();
Internally both methods create ThreadPoolExecutor with 1 thread so there is no actual difference between them only in naming.
If you're creating the objects immediately after one another (within the same ms), they'll probably have the same seed in their Random instances - therefore they'll sleep for the same amount of time.
From javadoc:
Creates a new random number generator. Its seed is initialized to a value based on the current time:
public Random() { this(System.currentTimeMillis()); }
Two Random objects created within the same millisecond will have the same sequence of random numbers.
Besides that there's a problem in your code.
Thread.yield();
is redundant.
If you need that to execute one by one you don't need thread pool. You may just invoke Sleep#run from within your for loop creating different instances of Sleep class.
If you need that to work using FixedThreadPool and you wanna exactly 3 separate threads done your work you should use Locks. Like this: First thread is locking your Lock on entrance and unlocking on exit. Next threads will wait for Lock to relase and do the same stuff.
Read more here:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html

Swing Worker Threads Not Concurrent

It seems that when I instantiate 12 Swing Worker threads, the first six starts to complete its task, it finishes AND then the last six starts and finishes. The behavior I'm looking for is all 12 threads start working at the same time & finish at the same time.
I have the following:
for (int i = 0; i < 12; i++ )
{
myTask m = new Mytask(i, START);
m.execute();
}
The myTask m will increment a progress bar from 0 - 100 in increments of 25. I'm getting outlandish behavior that the first six threads start incrementing, they finish at 100, then the last six threads start from 0 and increment, and finish.
Is there a limiting factor on the amount of Swing Worker threads one may have?
The behavior I'm looking for is all 12 threads start working at the same time & finish at the same time.
A CountDownLatch is designed for this very purpose. Here's a good example using a single SwingWorker and a number of subsidiary threads controlled by the latch.
SwingWorker class has a static ExecutorService field with MAX_WORKER_THREADS = 10. I'm not certain why you see 6 and not 10. But you cannot go over 10.
/**
* number of worker threads.
*/
private static final int MAX_WORKER_THREADS = 10;
...
executorService =
new ThreadPoolExecutor(1, MAX_WORKER_THREADS,
10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
Your question says:
The behavior I'm looking for is all 12
threads start working at the same time
& finish at the same time.
But you can't guarantee for all Swing workers threads starting concurrently and ending at same time.

Categories

Resources