straight to question. is Thread.join(x) starting the count from the moment start() method is called or from the moment join(x) method is called?
To demonstrate: which of the following solutions is the correct way of doing it?
Set<Thread> myThreads=new HashSet<Thread>();
for(Task t : tasks){
try{
Thread thread=new ConcurrentTask(t);
thread.start();
myThreads.add(thread);
Thread.sleep(1000);
}catch(Exception e){
}
}
//solution 1:
for(Thread t: myThreads){
try{
t.join(10000) //wait for at most 10 seconds
}catch(Exception e){}
}
//solution 2:
long maxWaitTime=System.currentTimeMillis()+ (10*1000);//max wait is 10 seconds;
for(Thread t: myThreads){
long threadWait=maxWaitTime - System.currentTimeMillis();
if(threadWait<100){
threadWait=100;
}
try{
t.join(threadWait) //wait for at most 10 seconds
}catch(Exception e){}
}
Since you are doing multiple threads and it looks like the maximum wait time for all threads is supposed to be 10 seconds, then option 2 is correct. Wait time is from the wait execution, it does not check on total thread execution time.
Related
Talk is cheap. Show the code.
MyCyclicBarrier.java
public class MyCyclicBarrier extends Thread{
private CyclicBarrier cyclicBarrier;
public MyCyclicBarrier(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
#Override
public void run() {
System.out.println("Thread start." + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(2); //biz code
System.out.println("Thread "+Thread.currentThread().getName()+" is waiting for the other Threads."+
"\n\t\t\t\tIt's parties is "+cyclicBarrier.getParties()+
"\n\t\t\t\tWaiting for "+cyclicBarrier.getNumberWaiting()+" Threads");
cyclicBarrier.await(3,TimeUnit.SECONDS);
} catch (InterruptedException | BrokenBarrierException | TimeoutException e) {
e.printStackTrace();
}
System.out.println("Thread end."+Thread.currentThread().getName());
}
}
TestCyclicbarrier.java
public class TestCyclicbarrier1 {
public static void main(String[] args) {
int length = 5;
long start = System.currentTimeMillis();
CyclicBarrier cyclicBarrierWithRunnable = new CyclicBarrier(length, () -> {
System.out.println("the final reach Thread is " + Thread.currentThread().getName());
long end = System.currentTimeMillis();
System.out.println("cost totally :" + (end - start) / 1000 + "s");
});
for (int i = 0; i < length; i++) {
if (i != 4) {
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} else {
try {
TimeUnit.SECONDS.sleep(2);
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Output:
Thread start.Thread-1
Thread start.Thread-0
Thread start.Thread-2
Thread start.Thread-3
Thread Thread-0 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread Thread-3 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread start.Thread-4
Thread Thread-1 is waiting for the other Threads.
It's parties is 5
Waiting for 0 Threads
Thread Thread-2 is waiting for the other Threads.
It's parties is 5
Waiting for 1 Threads
Thread Thread-4 is waiting for the other Threads.
It's parties is 5
Waiting for 4 Threads
the final reach Thread is Thread-4
cost totally :4s
Thread end.Thread-4
Thread end.Thread-0
Thread end.Thread-3
Thread end.Thread-2
Thread end.Thread-1
I am searching for a long time on net. But no similar answer. Please help or try to give some ideas! And I just start to learn CyclicBarrier.
I wonder if I have misunderstood CyclicBarrier.await(int timeout,TimeUnit unit). Threads 0 through 3 have already reached the barrier point that cost 2s.In the same time the final Thread started after 2s of waiting.After 1 second number 0 to 3 Threads reach the specified timeout which number 4 thread still excuted its own code. Here is the question: Why did CyclicBarrier.await(int timeout, TimeUnit unit) didn't throw TimeOutException here?
Threads 0 through 3 have already reached the Barrier point that cost 2s.
This is correct.
In the same time the final Thread started after 2s of waiting.
Correct. Note, by the time this thread starts, other 4 threads are awaiting the CB (3 secs timeout i.e., we have 3 secs until a TimeoutException can occur).
But thread 4 sleeps for only 2 seconds in the run method (we still have only 1 sec until the TimeoutException).
When it comes to await, it is the last thread - so it doesn't have to wait anymore. Hence the barrier action gets run and others are unblocked - from javadoc,
If the current thread is the last thread to arrive, and a
non-null barrier action was supplied in the constructor, then the current thread runs the action before allowing the other threads to continue.
If you make sleep for four seconds before starting thread-4, you would get a TimeoutException.
try {
TimeUnit.SECONDS.sleep(4);
new MyCyclicBarrier(cyclicBarrierWithRunnable).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
You seem to think that the timeout starts when the thread starts:
Threads 0 through 3 have already reached the Barrier point that cost 2s.
After 1 second number 0 to 3 Threads reach the specified timeout
This is wrong. When you call
cyclicBarrier.await(3,TimeUnit.SECONDS);
it doesn't matter how long it took the threads to reach that point - the timeout is 3 seconds from the moment the method cyclicBarrier.await() is called.
Since thread 4 has only an additional delay of 2 seconds it still arrives in time.
To clarify further this is what the timeline looks like:
t=0s
main() creates the CyclicBarrier and starts threads 0 to 3
the threads 0 to 3 start and call TimeUnit.SECONDS.sleep(2);
main calls TimeUnit.SECONDS.sleep(2);
t=2s
main() starts thread 4
the threads 0 to 3 awake, print out something and then call cyclicBarrier.await(3,TimeUnit.SECONDS); which means that they will be interrupted at t=5s (t=2s + 3s)
thread 4 stars and calls TimeUnit.SECONDS.sleep(2);
t=4s
thread 4 awakes, prints out something and then calls cyclicBarrier.await(3,TimeUnit.SECONDS);.
since now all threads are within cyclicBarrier.await(3,TimeUnit.SECONDS);, the condition for the CyclicBarrier is fulfilled and all threads continue
the timeout for thread 4 doesn't get used (because it is the last thread to reach the CyclicBarrier)
for threads 0 to 3 the timeout at t=5s is never reached
I am trying to measure the time that a thread takes to execute.
I have created a sample programme
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Sample {
public static void main(String[] args ) {
ThreadPoolExecutor exec = (ThreadPoolExecutor)Executors.newFixedThreadPool(1000);
for(int i=0; i<1000; i++) {
exec.execute(new Runnable() {
#Override
public void run() {
long start = System.currentTimeMillis();
try{
Thread.sleep(10000);
} catch(Exception ex) {
ex.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("[Sample] Thread id : " + Thread.currentThread().getId() + ", time : " + (end - start));
}
});
}
}
}
Each thread sleeps for 10 seconds. So the duration = (end - start) should be 10000. But some threads are taking more time than expected. I am guessing this also includes thread switching time and and blocking time. Is there a way to measure the exectution time in threaded programme in JAVA?
The thing is that I have a programme that makes network calls in threads. So even if the socket time out is say 60 seconds, the thread execution time is close to 2 minutes. My guess is that the above way of calculating execution time also accounts for thread switching time and blocking time. It is not measuring the actual thread execution time
Thanks.
For such cases I use JavaVisualVM, it is a very very handy tool for finding concurrency issues.
I ran your code locally and this is what visual VM shows me.
All of the threads have exactly the same sleep time, so the differences we are seeing in the console log are probably misleading.
I am executing a program for a network where i have a certain number of tasks execution in loop, it works fine but when there a any flaws occurs due to network problem it got stuck in one of any task. so i want to create a thread which start at the time when control goes in to loop and after some delay it terminate it self with continuing the process.
for example-
for ( /*itearting condition */)
{
//thread start with specified time.
task1;
task2;
task3;
//if any execution delay occur then wait till specified time and then
//continue.
}
Please give me some clue regarding this, a snippets can help me a lot as i need to fix it shortly.
A thread can only be terminated with its cooperation (assuming you want to save the process). With the thread's cooperation, you can terminate it with any termination mechanism it supports. Without its cooperation, it cannot be done. The usual way to do it is to design the thread to sanely handle being interrupted. Then you can have another thread interrupt it if too much time passes.
I think you may need something like this:
import java.util.Date;
public class ThreadTimeTest {
public static void taskMethod(String taskName) {
// Sleeps for a Random amount of time, between 0 to 10 seconds
System.out.println("Starting Task: " + taskName);
try {
int random = (int)(Math.random()*10);
System.out.println("Task Completion Time: " + random + " secs");
Thread.sleep(random * 1000);
System.out.println("Task Complete");
} catch(InterruptedException ex) {
System.out.println("Thread Interrupted due to Time out");
}
}
public static void main(String[] arr) {
for(int i = 1; i <= 10; i++) {
String task = "Task " + i;
final Thread mainThread = Thread.currentThread();
Thread interruptThread = new Thread() {
public void run() {
long startTime = new Date().getTime();
try {
while(!isInterrupted()) {
long now = new Date().getTime();
if(now - startTime > 5000) {
//Its more than 5 secs
mainThread.interrupt();
break;
} else
Thread.sleep(1000);
}
} catch(InterruptedException ex) {}
}
};
interruptThread.start();
taskMethod(task);
interruptThread.interrupt();
}
}
}
This question already has answers here:
ExecutorService, how to wait for all tasks to finish
(16 answers)
Closed 5 years ago.
I have a command line application. It runs a loop say 100 times and in the loop schedules a task using a thread. I am using ExecutorService so there are 4 threads running at any time.
After the loop ends, I want to print a summary message. E.g. time taken to complete all 100 tasks. When I stepped through the code the debugger went straight to the summary part, but the other tasks are still running. I understand this is because each thread runs on its own. So how do I print messages only after all threads complete?
ExecutorService exec = Executors.newFixedThreadPool(4);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
Runnable requestHandler = new Runnable() {
#Override
public void run() {
try {
// call task function in here
} catch (Exception ex) {
}
}
};
exec.execute(requestHandler);
}
exec.shutdown();
long endTime = System.currentTimeMillis();
LOGGER.info("******************SUMMARY******************");
LOGGER.info("Time taken : " + ((endTime - startTime)/1000) + " seconds, "
+ ((endTime - startTime)/1000/60) + " minutes");
From the main-thread, you could create another thread that does everything from declaring exec to exec.shutdown();. After creating this thread, you put the main-thread to wait. At the end of the new thread's actions(after exec.shutdown();) you should notify it.
See http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html example copied for brevity
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Basically you need to wait until the ExecutorService isTerminated() method returns true. You can use awaitTermination() to that end.
The solution for you based on your code:
ExecutorService exec = Executors.newFixedThreadPool(4);
long start = System.currentTimeMillis();
//Your code
exec.shutdown();
while(true) {
if(exec.isTerminated()) {
long end = System.currentTimeMillis();
System.out.println("Time : " + (end - start));
break;
}
Check this out! It works!
hi
i want a block of code(certain lines of a function) that will run for a stipulated amount of time (say x milliseconds).Is is possible to do this in java?
1st approach:
long startTime = System.nanoTime();
while(System.nanoTime() - startTime < MAX_TIME_IN_NANOSECONDS){
// your code ...
}
2nd approach
Start your code in thread.
Sleep main thread for as long as you need.
Kill (stop, interrupt) your thread.
either use an exit condition based on current timestamp, or create a separate thread and kill it after a specified timeout.
Run your method in a separate thread, but passing it to an Executor. You can then use the Future to wait a certain period of time for the the thread to complete. If it doesn't complete, you will get a TimeoutException and you can then cancel the thread. Cancelling the thread causes the thread to be interrupted. So your code will have to periodically check the thread's interrupted status and exit if necessary.
For example:
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Integer> future = exec.submit(new Callable<Integer>(){
#Override
public Integer call() throws Exception {
//do some stuff
//periodically check if this thread has been interrupted
if (Thread.currentThread().isInterrupted()) {
return -1;
}
//do some more stuff
//check if interrupted
if (Thread.currentThread().isInterrupted()) {
return -1;
}
//... and so on
return 0;
}
});
exec.shutdown();
try {
//wait 5 seconds for the task to complete.
future.get(5000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
//the task did not complete in 5 seconds
e.printStackTrace();
System.out.println("CANCELLING");
//cancel it
future.cancel(true); //sends interrupt
}
You could use Calendar:
timeInMilis = Calendar.getInstance().getTimeInMillis();
while(Calendar.getInstance().getTimeInMilis() - timeInMilis < MAX_TIME_IN_MILIS){
// Execute block
}
Check the time using System.currentTimeMillis() and exit your loop after the time has passed.
long endTime = System.currentTimeMillis() + ClassName.EXECUTION_TIME_MS;
while (System.currentTimeMillis() < endTime) {
// do your stuff
}
If you need to sleep inside the thread for some reason, adjust your sleep time to end at the end time.
long timeLeft = endTime - System.currentTimeMillis();
if (sleepAmount > timeLeft)
sleepAmount = timeLeft;
Thread.sleep(sleepAmount);
If you're going to use the wait() and notify() method, then use the calculated timeLeft as the argument to wait() to ensure the maximum wait time. Once that wait time hits, the method will return and the loop will break.
long timeLeft = endTime - System.currentTimeMillis();
if (timeLeft > 0)
this.wait(timeLeft);
If you're running multiple steps inside the loop which can take a long time, you should add additional checks between steps, if you want the process to break between steps, to exit the loop if the designated time has passed. This is a design decision. When the timer expires, do you want the task to finish up the step it's working on and then exit? It's up to you how to code it based on the desired result.
long endTime = System.currentTimeMillis() + ClassName.EXECUTION_TIME_MS;
while (System.currentTimeMillis() < endTime) {
this.doFirstLongThing();
if (System.currentTimeMillis() >= endTime) break;
this.doSecondLongThing();
if (System.currentTimeMillis() >= endTime) break;
this.doThirdLongThing();
}