I have a task where while generating a random password for user the SMS should go after 4 MIN, but the welcome SMS should go immediately. Since password I am setting first and need to send after 4 MIN I am making that thread sleep (Cant use ExecutorServices), and welcome SMS thread start.
Here is the code:
String PasswordSMS="Dear User, Your password is "+'"'+"goody"+'"'+" Your FREE
recharge service is LIVE now!";
String welcomeSMS="Dear goody, Welcome to XYZ";
try {
Thread q=new Thread(new GupShupSMSUtill(PasswordSMS,MOB_NUM));
Thread.sleep(4 * 60 * 1000);
q.start();
GupShupSMSUtill sendWelcomesms2=new GupShupSMSUtill(welcomeSMS, MOB_NUM);
Thread Bal3=new Thread(sendWelcomesms2);
Bal3.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
</code>
So if I change the order the thread sendWelcomesms2 Immediately starts.I have to send welcome SMS then password sms (After 4 Min) how its achievable ??
NOTE: Both SMS come after 4 MIN
Thread.sleep(4 * 60 * 1000);
delays execution of your currently running thread, your q.start() is not executed until the wait time is over. This order doesn't make sense.
Your thread is only created when
Thread q=new Thread(new GupShupSMSUtill(PasswordSMS,MOB_NUM));
is executed. Your thread is started when
q.start();
is executed. So if you want to achieve running the q thread while the main thread sleep, you should write your lines in this order:
Thread q=new Thread(new GupShupSMSUtill(PasswordSMS,MOB_NUM)); // Create thread
q.start(); // start thread
Thread.sleep(4 * 60 * 1000); // suspend main thread for 4 sec
You can use join():
String PasswordSMS = "Dear User, Your password is " + "\"" + "goody" + "\"" + " Your FREE recharge service is LIVE now!";
String welcomeSMS = "Dear goody, Welcome to XYZ";
try
{
GupShupSMSUtill sendWelcomesms2 = new GupShupSMSUtill(welcomeSMS, MOB_NUM);
Thread Bal3 = new Thread(sendWelcomesms2);
Bal3.start();
Thread q = new Thread(new GupShupSMSUtill(PasswordSMS, MOB_NUM));
q.start();
q.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
Or latch:
private static java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1);
And the code:
String PasswordSMS = "Dear User, Your password is " + "\"" + "goody" + "\"" + " Your FREE recharge service is LIVE now!";
String welcomeSMS = "Dear goody, Welcome to XYZ";
try
{
GupShupSMSUtill sendWelcomesms2 = new GupShupSMSUtill(welcomeSMS, MOB_NUM);
Thread Bal3 = new Thread(sendWelcomesms2);
Bal3.start();
Thread q = new Thread(new GupShupSMSUtill(PasswordSMS, MOB_NUM));
q.start();
latch.await(); // Wait
}
catch (InterruptedException e)
{
e.printStackTrace();
}
At the end of the Thread "q":
latch.countDown(); // stop to wait
Hint - Don't use Thread.sleep(x) in this case.
You are sleeping the current thread, before you issue the startcommand for q.
You probably want to issue the sleep inside GupShupSMSUtill() (maybe change its signature to something like GupShupSMSUtill(PasswordSMS,MOB_NUM, sleeptime) to be able to control how long it sleeps).
Related
I'm using interrupt() in my code to signal from a thread to another to wake up from "endless" (Maximum time) sleep and verify a condition in a while.
I'm using also monitor (synchronized block, notify and wait) and synchronized method. I wrote my code in the way that some thread sleeps until they got an interrupt but some interrupt wake up thread when they should not be awaken (they must simulate they are doing other things sleeping). The problem is that I'm not able to find the thread that do interrupt() when it should not, how can I found it?
Is a good way to code using interrupt() in this way?
That's the code in which sleep get interrupted but should not
private void medicalVisit(int number) {
long sleepTime = (long) ((Math.random() * 2 + 0.5) * 1000); // 500 <= sleepTime (in msec) <= 2500
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
System.out.println(this.getName()+" ERROR, interrupt from sleep, id: 2 (medicalVisit)");
e.printStackTrace();
}
System.out.println(this.getName()+" - "+number+"° medical visit ended");
}
This is an example of code that launch an interrupt
private void handlerYellowPatient() {
Iterator<Patient> patientIt = yellows.iterator();
while(patientIt.hasNext()) {
Patient p = patientIt.next();
p.itsTurn = true;
p.interrupt();
yellows.remove(p);
}
}
And this an example of code "consuming" interrupt properly
private void waitUntilItsTurn(int number) {
// simulating the period of time before entering in guard
long sleepTime = (long) ((Math.random() * 2 + 0.5) * 1000); // 500 <= sleepTime (in msec) <= 2500
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// must not be awaken while here
System.out.println(this.getName()+" ERROR MAYBE, interrupt from sleep, id: 1");
e.printStackTrace();
}
WMan.addPatient(this, WMan);
while (!itsTurn) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
// WMan handlerRedPatient interrupt#1
System.out.println(this.getName()+" - the wait is over, it's my turn for the "+number+"° times");
}
}
itsTurn = false;
}
Hoping these code can help
I have a scheduled executor to reset a parameter to 0 and awake all active threads to continue processing. However after initial run of the thread it is not executing again.
ScheduledExecutorService exec = Executors.newScheduledThreadPool(4);
exec.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
logger.info("Setting hourly limit record count back to 0 to continue processing");
lines = 0;
executor.notifyAll();
Thread.currentThread().interrupt();
return;
}
}, 0, 1, TimeUnit.MINUTES);
There is another Executor defined in the class which executes further processes and not sure if this influences it:
ExecutorService executor = Executors.newCachedThreadPool();
for (String processList : processFiles) {
String appName = processList.substring(0,processList.indexOf("-"));
String scope = processList.substring(processList.lastIndexOf("-") + 1);
logger.info("Starting execution of thread for app " + appName + " under scope: " + scope);
try {
File processedFile = new File(ConfigurationReader.processedDirectory + appName + "-" + scope + ".csv");
processedFile.createNewFile();
executor.execute(new APIInitialisation(appName,processedFile.length(),scope));
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
From the documentation for ScheduledExecutorService.scheduleAtFixedRate():
If any execution of the task encounters an exception, subsequent executions are suppressed.
So something in your task is throwing an exception. I would guess the call to executor.notifyAll() which is documented to throw an IllegalMonitorStateException:
if the current thread is not the owner of this object's monitor.
Your scheduled task will most probably end up in a uncaught Exception. Taken from the JavaDoc of ScheduledExecutorService.scheduleAtFixedRate
If any execution of the task encounters an exception, subsequent
executions are suppressed.
Because you are provoking a uncaught exception, all further executions are cancelled.
This question already has answers here:
If I synchronized two methods on the same class, can they run simultaneously?
(12 answers)
Closed 5 years ago.
I have created a simple Worker :
public class Worker {
public synchronized void writeData() {
try {
System.out.println("write Data , thread id = " + Thread.currentThread().getId());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void readData() {
try {
System.out.println("readData , thread id = " + Thread.currentThread().getId());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
AFAIK, If multiple thread access the same Worker instance, the synchronized only blocks threads that access the same method. AKA if thread A invokes writeData and B uses readData, they will not influence each other (Correct me if I am wrong).
BUT, when I tried to demo it by the code below:
private static void testWithThreads() {
final Worker worker = new Worker();
new Thread(() -> {
System.out.println("start read thread");
for (int i = 0; i < 20; i++) {
worker.readData();
}
}).start();
new Thread(() -> {
System.out.println("start write thread");
for (int i = 0; i < 20; i++) {
worker.writeData();
}
}).start();
}
I got the output like this (Note that we have Thread.sleep for 2 seconds here):
start read thread
readData , thread id = 10
start write thread
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
Can anyone explain this to me? It seems they blocked each other in some way.
the synchronized only blocks threads that access the same method
Wrong. It blocks threads trying to synchronize on the same object.
How it works is if A is using writeData for a Worker instance then B cannot use readData or writeData from the same Worker until it is given a chance.
If you were hoping to have your output to be:
read
write
read
write
etc...
then I would suggest using the functions wait(); and notifyAll();
This way you can make thread A give Thread B a turn once it is finished and vice versa.
You can read more about wait() and notifyAll()
here.
synchronized on a method level synchronizes access to all synchronized methods of the Object the methods belongs to, that only one thread can execute in any synchronized method of that object. The other threads will wait even if they try to access other synchronized method than the first thread.
The other Threads will block till the first one will get out from the synchronized blocks.
In your code beetween the invocation of synchornized methods in for loops, there is tiny time slot in which other thread can get into the writeData() before the first get again into readData() - a typical for loop is not atomic operation - but this time slot is so tiny, that it rarely happens - so your output looks like they are blocking each other in some way - and in one point the wind changes and other thread takes the lead.
to be more specific, comments are pointing where "unsynchronized" time slot begins in each for loop:
private static void testWithThreads() {
final Worker worker = new Worker();
new Thread(() -> {
System.out.println("start read thread");
for (int i = 0; i < 20; i++) {
worker.readData();
// any thread can now invoke writeData() if current thread is before next invocation of worker.readData();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
System.out.println("start write thread");
for (int i = 0; i < 20; i++) {
worker.writeData();
// any thread can now invoke readData() if current thread is before next invocation of worker.writeData();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
If you want to have better interleaving you can do one of these things:
use wait() and notify()
do not use synchronization on that methods - synchronize the
data.
move the sleep operation outside the synchronized write and read methods,
they will give the threads more chance to get into the
synchronized block.
I have a callable which starts a Thread(this Thread runs a ping process) I want to allow the user to cancel the tasks:
public class PingCallable implements Callable<PingResult> {
private ProcThread processThread;
public PingCallable(String ip) {
this.processThread = new ProcThread(ip);
}
#Override
public PingResult call() throws Exception {
log.trace("Checking if the ip " + ip + " is alive");
try {
processThread.start();
try {
processThread.join();
} catch (InterruptedException e) {
log.error("The callable thread was interrupted for " + processThread.getName());
processThread.interrupt();
// Good practice to reset the interrupt flag.
Thread.currentThread().interrupt();
}
} catch (Throwable e) {
System.out.println("Throwable ");
}
return new PingResult(ip, processThread.isPingAlive());
}
}
The ProcThread, looks something like:
#Override
public void run() {
try {
process = Runtime.getRuntime().exec("the long ping", null, workDirFile);
/* Get process input and error stream, not here to keep it short*/
// waitFor is InterruptedException sensitive
exitVal = process.waitFor();
} catch (InterruptedException ex) {
log.error("interrupted " + getName(), ex);
process.destroy();
/* Stop the intput and error stream handlers, not here */
// Reset the status, good practice
Thread.currentThread().interrupt();
} catch (IOException ex) {
log.error("Exception while execution", ex);
}
}
And the test:
#Test
public void test() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(15);
List<Future<PingResult>> futures = new ArrayList<>();
for (int i= 0; i < 100; i++) {
PingCallable pingTask = new PingCallable("10.1.1.142");
futures.add(executorService.submit(pingTask));
}
Thread.sleep(10000);
executorService.shutdownNow();
// for (Future<PingResult> future : futures) {
// future.cancel(true);
// }
}
I monitor the ping processes using ProcessExplorer, I see 15, then the shutdownNow is executed, or future.cancel(true), only 4-5 max 8 processes are interrupted, the rest are left alive, I almost never see 15 messages saying "The callable thread was interrupted..", and the test does not finish until the processes end. Why is that?
I might not have a complete answer but there are two things to note:
shutdownNow signals a shutdown, to see if threads are actually stopped, use awaitTermination
process.destroy() also takes time to execute so the callable should wait for that to complete after interrupting the process-thread.
I modified the code a little and found that future.cancel(true) will actually prevent execution of anything in the catch InterruptedException-block of ProcThread, unless you use executor.shutdown() instead of executor.shutdownNow(). The unit-test does finish when "Executor terminated: true" is printed (using junit 4.11).
It looks like using future.cancel(true) and executor.shutdownNow() will double-interrupt a thread and that can cause the interrupted-blocks to be skipped.
Below the code I used for testing. Uncomment for (Future<PingResult> f : futures) f.cancel(true); together with shutdown(Now) to see the difference in output.
public class TestRunInterrupt {
static long sleepTime = 1000L;
static long killTime = 2000L;
#Test
public void testInterrupts() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
List<Future<PingResult>> futures = new ArrayList<Future<PingResult>>();
for (int i= 0; i < 100; i++) {
PingCallable pingTask = new PingCallable("10.1.1.142");
futures.add(executorService.submit(pingTask));
}
Thread.sleep(sleepTime + sleepTime / 2);
// for (Future<PingResult> f : futures) f.cancel(true);
// executorService.shutdown();
executorService.shutdownNow();
int i = 0;
while (!executorService.isTerminated()) {
System.out.println("Awaiting executor termination " + i);
executorService.awaitTermination(1000L, TimeUnit.MILLISECONDS);
i++;
if (i > 5) {
break;
}
}
System.out.println("Executor terminated: " + executorService.isTerminated());
}
static class ProcThread extends Thread {
static AtomicInteger tcount = new AtomicInteger();
int id;
volatile boolean slept;
public ProcThread() {
super();
id = tcount.incrementAndGet();
}
#Override
public void run() {
try {
Thread.sleep(sleepTime);
slept = true;
} catch (InterruptedException ie) {
// Catching an interrupted-exception clears the interrupted flag.
System.out.println(id + " procThread interrupted");
try {
Thread.sleep(killTime);
System.out.println(id + " procThread kill time finished");
} catch (InterruptedException ie2) {
System.out.println(id + "procThread killing interrupted");
}
Thread.currentThread().interrupt();
} catch (Throwable t) {
System.out.println(id + " procThread stopped: " + t);
}
}
}
static class PingCallable implements Callable<PingResult> {
ProcThread pthread;
public PingCallable(String s) {
pthread = new ProcThread();
}
#Override
public PingResult call() throws Exception {
System.out.println(pthread.id + " starting sleep");
pthread.start();
try {
System.out.println(pthread.id + " awaiting sleep");
pthread.join();
} catch (InterruptedException ie) {
System.out.println(pthread.id + " callable interrupted");
pthread.interrupt();
// wait for kill process to finish
pthread.join();
System.out.println(pthread.id + " callable interrupt done");
Thread.currentThread().interrupt();
} catch (Throwable t) {
System.out.println(pthread.id + " callable stopped: " + t);
}
return new PingResult(pthread.id, pthread.slept);
}
}
static class PingResult {
int id;
boolean slept;
public PingResult(int id, boolean slept) {
this.id = id;
this.slept = slept;
System.out.println(id + " slept " + slept);
}
}
}
Output without future.cancel(true) or with future.cancel(true) and normal shutdown():
1 starting sleep
1 awaiting sleep
2 starting sleep
3 starting sleep
2 awaiting sleep
3 awaiting sleep
1 slept true
3 slept true
2 slept true
5 starting sleep
4 starting sleep
6 starting sleep
5 awaiting sleep
6 awaiting sleep
4 awaiting sleep
4 callable interrupted
Awaiting executor termination 0
6 callable interrupted
4 procThread interrupted
5 callable interrupted
6 procThread interrupted
5 procThread interrupted
Awaiting executor termination 1
6 procThread kill time finished
5 procThread kill time finished
4 procThread kill time finished
5 callable interrupt done
5 slept false
6 callable interrupt done
4 callable interrupt done
6 slept false
4 slept false
Executor terminated: true
Output with future.cancel(true) and shutdownNow():
1 starting sleep
2 starting sleep
1 awaiting sleep
2 awaiting sleep
3 starting sleep
3 awaiting sleep
3 slept true
2 slept true
1 slept true
4 starting sleep
6 starting sleep
5 starting sleep
4 awaiting sleep
5 awaiting sleep
6 awaiting sleep
5 callable interrupted
6 callable interrupted
4 callable interrupted
5 procThread interrupted
6 procThread interrupted
4 procThread interrupted
Executor terminated: true
Yesterday I ran a series of tests, one of the most fruitful involved:
Interrupting the threads which run the procces, checking that it was interrupted, and that the process nevertheless was still hanging on "waitFor",
I decided to investigate why was the process not detecting that the thread in which it was running was interrupted.
I found that it is crucial to handle the streams (output, input and error) correctly otherwise the external process will block on I/O buffer.
I noticed that my error handler was also blocking on reading (no error output), don't know if it's an issue, but I decided to follow the suggestion and redirect the err stream to out stream
Finally I discovered that there is a correct way to invoke and destroy processes in Java
New ProcThread (As #pauli suggests, it does not extend from THREAD anymore! Run's in a callable, I keep the name so the difference can be noticed) looks like:
try {
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.directory(new File(workDir));
builder.redirectErrorStream(true);
process = builder.start();
// any output?
sht= new StreamHandlerThread(process.getInputStream(), outBuff);
sht.start();
// Wait for is InterruptedException sensitive, so when you want the job to stop, interrupt the thread.
exitVal = process.waitFor();
sht.join();
postProcessing();
log.info("exitValue: %d", exitVal);
} catch (InterruptedException ex) {
log.error("interrupted " + Thread.currentThread().getName(), ex);
shutdownProcess();
The shutdown process:
private void shutdownProcess() {
postProcessing();
sht.interrupt();
sht.join();
}
The postProcessing:
private void postProcessing() {
if (process != null) {
closeTheStream(process.getErrorStream());
closeTheStream(process.getInputStream());
closeTheStream(process.getOutputStream());
process.destroy();
}
}
So the title is explanatory, I want to wait on a thread for a max time say 1 sec, now within this 1 sec if the other thread receives a response then its fine, otherwise after 1 sec whether or not a response is recieved it should stop waiting and continue with its work, later I can wait for another 2 seconds to see if the response has arrived
Main Class:
atiReq.Now(); //asynchronous method returns immediatly
firstATIState = atiReq.getState(1000); // Wait for a max of 1000 ms to get the response
}
handleIDP();
if (isMobSub && firstATIState == null) {
//If ati response was not recived previously wait for another maximum 2000 ms now
firstATIState = atiReq.getState(2000);
}
AtiRequest Class:
/**
* Does an ATI Request asynchrounously
*/
public void Now() {
new Thread() {
public void run() {
atiReq.run();
synchronized (atiReq) {
try {
atiReq.wait(3000);
rawResponse = atiReq.ReturnXML;
logger.info("[" + refID + "] ATI Response recieved: " + rawResponse);
atiResponseRecieved = true;
atiReq.notify();
} catch (InterruptedException ex) {
logger.error("Error waiting on atiReq", ex);
}
}
}
}.start();
}
public String GetRawResponse() {
return rawResponse;
}
/**
* Gets the state of the ATI performed, waits for the ATI response for max
* period of timeout specified, returns null if response not arrived in
* specified time
*
* #param timeout the time to wait for response in milliseconds
* #return
*/
public ATIState getState(long timeout) {
synchronized (atiReq) {
while (!atiResponseRecieved) {
try {
atiReq.wait(timeout);
} catch (InterruptedException ex) {
logger.error("Error waiting on atiReq while trying to get aitState", ex);
}
}
}
if ("".equals(this.rawResponse)) {
//Response not recieved yet
logger.info("[" + refID + "] ATI Response not recived yet");
return null;
}
ATIState atiState = new ATIState(this.rawResponse);
return atiState;
}
Problem:
firstATIState = atiReq.getState(1000);
This line, in the main class, doesnt terminate after 1 sec, as you can see the corresponding code in getState(long timeout) method
while (!atiResponseRecieved) {
try {
atiReq.wait(timeout);
} catch (InterruptedException ex) {
logger.error("Error waiting on atiReq while trying to get aitState", ex);
}
}
is in a loop so I believe even if atiReq.wait(timeout) returns within 1 sec and if atiResponseRecieved is not true, it keeps on looping till the timeout of the Now() method exhausts and it sets atiResponseRecieved to true;
Question:
How do I solve this?
I have tried removing it from the loop but then "spurious awakes" dont let it wait for complete 1 sec.
Is there any other work around for this?
You can use Futuretask (or just Future). for this. It has a get() method that allows you to specify a timeout.