In the code, the variable timer would specify the duration after which to end the while loop, 60 sec for example.
while(timer) {
//run
//terminate after 60 sec
}
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// run
}
you should try the new Java Executor Services.
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
With this you don't need to program the loop the time measuring by yourself.
public class Starter {
public static void main(final String[] args) {
final ExecutorService service = Executors.newSingleThreadExecutor();
try {
final Future<Object> f = service.submit(() -> {
// Do you long running calculation here
Thread.sleep(1337); // Simulate some delay
return "42";
});
System.out.println(f.get(1, TimeUnit.SECONDS));
} catch (final TimeoutException e) {
System.err.println("Calculation took to long");
} catch (final Exception e) {
throw new RuntimeException(e);
} finally {
service.shutdown();
}
}
}
If you can't go over your time limit (it's a hard limit) then a thread is your best bet. You can use a loop to terminate the thread once you get to the time threshold. Whatever is going on in that thread at the time can be interrupted, allowing calculations to stop almost instantly. Here is an example:
Thread t = new Thread(myRunnable); // myRunnable does your calculations
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000L;
t.start(); // Kick off calculations
while (System.currentTimeMillis() < endTime) {
// Still within time theshold, wait a little longer
try {
Thread.sleep(500L); // Sleep 1/2 second
} catch (InterruptedException e) {
// Someone woke us up during sleep, that's OK
}
}
t.interrupt(); // Tell the thread to stop
t.join(); // Wait for the thread to cleanup and finish
That will give you resolution to about 1/2 second. By polling more often in the while loop, you can get that down.
Your runnable's run would look something like this:
public void run() {
while (true) {
try {
// Long running work
calculateMassOfUniverse();
} catch (InterruptedException e) {
// We were signaled, clean things up
cleanupStuff();
break; // Leave the loop, thread will exit
}
}
Update based on Dmitri's answer
Dmitri pointed out TimerTask, which would let you avoid the loop. You could just do the join call and the TimerTask you setup would take care of interrupting the thread. This would let you get more exact resolution without having to poll in a loop.
Depends on what the while loop is doing. If there is a chance that it will block for a long time, use TimerTask to schedule a task to set a stopExecution flag, and also .interrupt() your thread.
With just a time condition in the loop, it could sit there forever waiting for input or a lock (then again, may not be a problem for you).
Related
i want to terminate some process after some time if that process will not responded
i used this code but i am not able to achive the same
long start = System.currentTimeMillis(); long end = start +60000;
1 while (System.currentTimeMillis() < end)
2 {
3 Connection.execute(function); // execute
4 break; // break if response came
5 }
6 if(System.currentTimeMillis() > end)
7 {
8 close connection; // close connection if line no 3 will not responded
9 }
kindly help me on the same
As the call Connection.execute() is blocking, so main thread will be blocked until it executes, SO in that case if we want to close the connection when the main thread is blocked , we have to close connection in some other thread. May be we can use Timer & TimerTask in this case. I tried to write some code as below, May be you can some thing like that.
Timer timer = new Timer();
while (System.currentTimeMillis() < end) { //In any case, this loop runs for only one time, then we can replace it with IF condition
CloseConnectionTask task = new CloseConnectionTask(Connection);
timer.schedule(task, end); // Task will be excuted after the delay by "end" milliseconds
Connection.execute(function); // execute
task.cancel(); //If the excute() call returns within time ie. "end" milliseconds, then timerTask will not get executed.
break; // break if response came//
}
timer.cancel(); // If you have no more scheduling tasks, then timer thread should be stopped.
Below is TimerTask implementation:
class CloseConnectionTask extends TimerTask {
private Connection con;
public CloseConnectionTask(Connection con) {
this.con = con;
}
#Override
public void run() {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Note: I have one more thing to say, In your while loop, If the call to Connection.execute() successful, then you break from the loop. So what I have observed, In any case your loop is executing only once, If this is the case, then you should use IF(again its what I have seen in the provided code, you requirement may be different). Hope it may help you. If you have other thoughts on this, please share. My answer is based on this link, Good info. is there.
this way it will not help
i think you should implement thread to achieve that
I'm trying to limit attempts of a process in a loop to 60 seconds by sleeping for 3,000ms per loop with 20 attempts. Calling Thread.sleep() isn't actually pausing execution in the thread that's running and instead, all 20 attempts happen rapidly in succession.
private void pollWebServiceForToken() {
final int pollInterval = 3000;
new Thread() {
#Override
public void run() {
int attempts = 0;
int maxAttempts = 60;
String token;
do {
token = requestToken(exchangeCode);
if (token.contains(FAILED)) {
try {
Thread.sleep(pollingInterval);
} catch (InterruptedException ex) {
this.currentThread().interrupt();
}
}
attempts++;
} while (token.toLowerCase().contains(FAILED) && attempts < maxAttempts && !cancelled);
}
}.start();
}
Since this is all happening inside of a Vaadin application, I'm assuming the wrong Thread is being put to sleep but I'm not sure how to target a specific thread for sleeping.
Thanks in advance
Are you sure the code inside the if is being run? The condition on the while is different (+toLowerCase). Thread.sleep() always causes the current thread to sleep.
How do I delay a while loop to 1 second intervals without slowing down the entire code / computer it's running on to the one second delay (just the one little loop).
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
It seems your loop runs on Main thread and if you do sleep on that thread it will pause the app (since there is only one thread which has been paused), to overcome this you can put this code in new Thread that runs parallely
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
//do stuff
}
My simple ways to delay a loop.
I already put the codes here after failing to follow the stackoverflow's standards.
//1st way: Thread.sleep : Less efficient compared to 2nd
try {
while (true) {//Or any Loops
//Do Something
Thread.sleep(sleeptime);//Sample: Thread.sleep(1000); 1 second sleep
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//================================== Thread.sleep
//2nd way: Object lock waiting = Most efficient due to Object level Sync.
Object obj = new Object();
try {
synchronized (obj) {
while (true) {//Or any Loops
//Do Something
obj.wait(sleeptime);//Sample obj.wait(1000); 1 second sleep
}
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//=============================== Object lock waiting
//3rd way: Loop waiting = less efficient but most accurate than the two.
long expectedtime = System.currentTimeMillis();
while (true) {//Or any Loops
while(System.currentTimeMillis() < expectedtime){
//Empty Loop
}
expectedtime += sleeptime;//Sample expectedtime += 1000; 1 second sleep
//Do Something
}
//===================================== Loop waiting
As Jigar has indicated you can use another Thread to do work which can operate, sleep etc independently of other Threads. The java.util.Timer class might help you as well since it can perform periodic tasks for you without you having to get into multithreaded programming.
I have a scenario where i want a thread to sleep for specific amount of time.
Code:
public void run(){
try{
//do something
Thread.sleep(3000);
//do something after waking up
}catch(InterruptedException e){
// interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
}
}
Now how do i handle the case where the thread i am trying to run is hit with an interrupted exception before the complete of the sleep? Also does the thread wake up after being interrupted and does it go to runnable state or when is it that only after it goes to runnable does the flow go to catch block?
When your thread is hit by an interrupt it will go into the InterruptedException catch block. You can then check how much time the thread has spent sleeping and work out how much more time there is to sleep. Finally, instead of swallowing the exception, it is good practice to restore the interruption status so that code higher up the call stack can deal with it.
public void run(){
//do something
//sleep for 3000ms (approx)
long timeToSleep = 3000;
long start, end, slept;
boolean interrupted;
while(timeToSleep > 0){
start=System.currentTimeMillis();
try{
Thread.sleep(timeToSleep);
break;
}
catch(InterruptedException e){
//work out how much more time to sleep for
end=System.currentTimeMillis();
slept=end-start;
timeToSleep-=slept;
interrupted=true
}
}
if(interrupted){
//restore interruption before exit
Thread.currentThread().interrupt();
}
}
According to this page you'll have to code it to behave the way you want. Using the thread above your sleep will be interrupted and your thread will exit. Ideally, you'd re-throw the exception so that whatever started the thread could take appropriate action.
If you don't want this to happen, you could put the whole thing in a while(true) loop. Now when the interrupt happens the sleep is interrupted, you eat the exception, and loop up to start a new sleep.
If you want to complete the 3 seconds of sleep, you can approximate it by having, say, 10 sleeps of 300 milliseconds, and keeping the loop counter outside a while loop. When you see the interrupt, eat it, set a "I must die" flag, and continue looping until you have slept enough. Then you interrupt the thread in a controlled manner.
Here's one way:
public class ThreadThing implements Runnable {
public void run() {
boolean sawException = false;
for (int i = 0; i < 10; i++) {
try {
//do something
Thread.sleep(300);
//do something after waking up
} catch (InterruptedException e) {
// We lose some up to 300 ms of sleep each time this
// happens... This can be tuned by making more iterations
// of lesser duration. Or adding 150 ms back to a 'sleep
// pool' etc. There are many ways to approximate 3 seconds.
sawException = true;
}
}
if (sawException) Thread.currentThread().interrupt();
}
}
using Sleep in my experience is usually to compensate for bad timing somewhere else in the program, reconsider!
try this:
public void run(){
try{
//do something
long before = System.currentTimeMillis();
Thread.sleep(3000);
//do something after waking up
}catch(InterruptedException e){
long diff = System.currentTimeMillis()-before;
//this is approximation! exception handlers take time too....
if(diff < 3000)
//do something else, maybe go back to sleep.
// interrupted exception hit before the sleep time is completed.so how do i make my thread sleep for exactly 3 seconds?
}
}
if you do not interrupt the sleep yourself, why would this thread be awoken ? is seems that you are doing something very wrong...
I use it this way:
So it is not necessary to wait the specific time to end.
public void run(){
try {
//do something
try{Thread.sleep(3000);}catch(Exception e){}
//do something
}catch(Exception e){}
}
Why do you want to sleep for exactly 3 seconds? If it's just having to execute something after some time, try using a Timer.
I need to create a java function that will only run for 30 minutes, and at the end of the 30 minutes it executes something. But it should also be able to self terminate before the given time if the right conditions are met. I don't want the function to be sleeping as it should be collecting data, so no sleeping threads.
Thanks
Use: Timer.schedule( TimerTask, long )
public void someFunctino() {
// set the timeout
// this will stop this function in 30 minutes
long in30Minutes = 30 * 60 * 1000;
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
if( conditionsAreMet() ) {
System.exit(0);
}
}
}, in30Minutes );
// do the work...
.... work for n time, it would be stoped in 30 minutes at most
... code code code
}
Get the start time with System.currentTimeMillis(), calculate the time when to stop and check the current time every now and then while you're collecting the data you want to collect. Another way would be to decouple the timer and the data collecting, so that each of them could run in their own threads.
For a more specific answer, it would be helpful if you would tell what data you are collecting and how you are collecting it.
Something like this will work:
long startTime = System.currentTimeMillis();
long maxDurationInMilliseconds = 30 * 60 * 1000;
while (System.currentTimeMillis() < startTime + maxDurationInMilliseconds) {
// carry on running - 30 minutes hasn't elapsed yet
if (someOtherConditionIsMet) {
// stop running early
break;
}
}
The modern java.util.concurrent way would be using ExecutorService. There are several invoke methods taking a timeout.
Here's a kickoff example:
public static void main(String args[]) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 30, TimeUnit.MINUTES);
executor.shutdown();
}
where Task look like this:
public class Task implements Callable<String> {
#Override
public String call() {
// Just a dummy long running task.
BigInteger i = new BigInteger("0");
for (long l = 0; l < Long.MAX_VALUE; l++) {
i.multiply(new BigInteger(String.valueOf(l)));
// You need to check this regularly..
if (Thread.interrupted()) {
System.out.println("Task interrupted!");
break; // ..and stop the task whenever Thread is interrupted.
}
}
return null; // Or whatever you'd like to use as return value.
}
}
See also:
Lesson: Concurrency