I am calling a thread inside while loop to sleep for 1 sec. While the flag is true, loop will be running (flag is true for infinite time).
Inside the loop thread should sleep for 1 second, wakes up and increase the counter, checks the IF condition and on FALSE condition it should sleep again for 1 sec and the process continues 29 times. On the 30th iteration IF condition will be true and the method called inside IF statement will collect and store a data. Finally on the 32nd iteration method called inside second IF statement will send the stored data to the server and sets the count = 0.
The problem is, sometimes sleep thread is sleeping for more than 1 min or sleeps for indefinite time period. Find here my enclosed piece of code.
public class NetworkThread implements Runnable {
private boolean flag;
public NetworkThread(boolean bool) {
flag = bool;
isrunning();
}
private boolean isrunning() {
return flag;
}
int counter = 0;
#Override
public void run() {
sendStartPacket();
while (flag) {
try {
Thread.sleep(1000);
counter++;
if (counter % 30 == 0) {
// TODO Auto-generated method store an information
}
if (counter % 32 == 0) {
// TODO Auto-generated method send the information to server
}
} catch (Exception e) {
e.toString();
}
}
}
private void sendStartPacket() {
// TODO Auto-generated method stub
}
Reset your counter! in the missing final clause and rewrite your check if (counter >= 30)
Apart from the complexity of your code/implementation, keep in mind that Thread.sleep() will try to sleep at least for x time, so it isn't strange that it's sleeping "more".
You can get more info about the accuracy of Thread.sleep() in this SO question.
This is the explanation for the case when your app seems to sleep more than desired. For indefinite sleep, I'm with Mike Murphy's comment, check your catch blocks
If your thread is interrupted, the counter is not increased and the thread sleeps for another 1000 ms. Perhaps that is the reason to your problem?
Related
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.
I have a producer that produces products and a consumer that consumes them. What I want is, if a product is not consumed in 5 minutes I want it to be destroyed.
This is the part of the producer:
boolean full = false;
public void produce(int p) throws RemoteException {
//choses a or b randomly
//if a or b spot is occupied, thread must wait()
synchronized(this){
if ((int)((Math.random()*10)%2) == 1){
while (a!=-1){try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(CHServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
a = p;
if (b!=-1) full = true;
notifyAll();
}
else {
while (b!=-1){try {
wait();
} catch (InterruptedException ex) {
Logger.getLogger(CHServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
b = p;
if (a!=-1) full = true;
notifyAll();
}
}
}
a & b are supposed to be my products.
I really don't know how can I measure that time for example when the thread is waiting or a client isn't trying to consume that product. This piece of code , is running on a RMI java server.
I'd just using a scheme like this: when you produce something use java.util.Timer() to set a timer for 5 minutes in the future. When the item is consumed, .cancel() the timer. If the timer goes off, do whatever cleanup you need to do.
It looks like you are implementing a queue with 2 slots, the 2 slots being a and b. But the strategy of chosing a random slot isn't optimal. You might wait for a slot while the other is empty. Also, the consumer cannot tell which one of a or b you produced first.
Anyway, if I understand the code well, you could
save the current time at the time you enter the loop.
every time you wake up from wait(), compute the delay since the entry. If it exceeds your time limit, return or throw an exception. Else, check if the slot is available.
to make sure not to wait forever, you should specify a delay on your wait. You could either wait a fixed time, maybe 1 second, or compute the wait time remaining until the 5-minute deadline.
I am running my java listener codes.
What happens is that my server will send some command to the client.
Thereafter I want to wait and see in 10s if there is no reply, then keep retrying for 5 times.
Below is what I do.
//Select code from the db with the codeID, codeText.
//send the code to the client.
long t= System.currentTimeMillis();
long end = t+10000;
while(System.currentTimeMillis() < end) {
}
//Select from db to check if codeupdated.
If updated dont do anything else I need to repeat the above pause ?
I having issue to repeat it for 5 times?
There is no guarantee for your construct to last exactly 10 seconds, and it's very costly in terms of performance.
Just use Thread.sleep.
for (int i = 0; i < 5; i++) {
// TODO your request here
boolean success = true; // TODO change to whatever outcome of your
// request
if (success) {
break;
}
else {
try {
Thread.sleep(10000l);
}
catch (InterruptedException ie) {
// TODO handle interruptions if applicable
}
}
}
Use
Thread.sleep(10*1000); //sleep 10 seconds.
You should use Thread.sleep() to pause execution
It's well explained here :
http://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html
I have a program that runs simultaneously and I have this problem where I want to stop the thread but the for loop/while loop doesn't get cancelled once I once I click enter
If I take the for loop out of the while loop, the program actually responds to the enter and shuts down.
class MyNumber extends Thread {
private volatile boolean processing = true;
public void run() {
while (processing) {
// Once I take this for loop out(put // beside it like right now), the enter key to stop the program then does work.
//for(int i = 1; i<27; i++){
System.out.println("Letter " + "i");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// }
}
}
public void permSleep() {
processing = false;
}
}
public class LetterNumber {
public static void main(String[] args) {
MyNumber num1 = new MyNumber();
num1.start();
System.out.println("Hit enter to stop the Numbers!");
Scanner shutter1 = new Scanner(System.in);
shutter1.nextLine();
num1.permSleep();
}
}
Why does the for loop cause the program to not shutdown?
I'm not really clear on what you're asking. However, if you're expecting that the while and for loops will both terminate as soon as processing is set to true, that isn't what happens. A while will execute the statement in the body (i.e. the for loop), then it will test the condition (processing == true), then if it's true, it executes the statement again, and then tests the condition again. It doesn't test it while the for loop is executing. It doesn't "notice" when the processing variable is set. So when processing is set to true, the for loop will keep going until it's done, which could be another 26 seconds.
To fix this simply, add
if (!processing)
break;
inside the for loop. Now the processing flag will be tested each time through the for loop. (If it were me, I'd put a "label" on the while loop and use that to break out of both loops.) Another way to fix it:
for(int i = 1; i<27 && processing; i++){
which means the for loop will continue only as long as processing is true.
Note: These solutions will still not test processing while the sleep(1000) is going on. So the program could still pause up to 1 second before it terminates. If you really want a solution that will terminate the sleep, you'll have use interrupt or some other concurrency feature.
It should work. Your for loop takes about 27 seconds to finish. It should come out of that after the for loop has finished.
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).