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
Related
For example:
HttpClient hc =...
...
//need a wait time(Thread.sleep(xxx)) here before executing
hc.execute(post)
...
//need a wait time(Thread.sleep(xxx)) here before executing
hc.execute(get)
...
...
What's the best way to do it? Thanks a lot for any suggest.
It depends if you want at least a certain amount of time to wait. Thread.sleep is not guaranteed to sleep the time you provide as argument.
Also sleep can be interrupted, so you need to take this into account.
You can do something like this:
public static void waitAtLeast(long millis) {
long startTime = System.nanoTime();
while (true) {
long now = System.nanoTime();
long timeWaited = (now - startTime) / 1000000L;
if (timeWaited > millis) {
return;
}
try {
Thread.sleep(millis - timeWaited);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
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).
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();
}
}
I have a string parser (parsing large text blobs) that needs to be run in a java fork join pool. The pool is faster than other threading and has reduced my parsing time by over 30 minutes when using both regular expressions and xpath. However, the number of threads being created climbs dramatically and I need to be able to terminate them since the thread pool is called multiple times. How can I reduce the increase in threads without limiting the pool to just 1 core on a 4 core system?
My thread count is exceeding 40000 and I need it to be closer to 5000 since the program is running 10 times with a stone cold execution limit of 50000 threads for my user.
This issue is happening on both Windows and Linux.
I am:
setting the max processors to the number of available processors*configurable number which is currently 1
cancelling tasks after get() is called
desperately setting the forkjoin pool to null before reinstantiating because I am desperate
Any Help would be appreciated. Thanks.
Here is the code I am using to stop, get and restart the pool. I should probably also note that I am submitting each task with fjp.submit(TASK) and then invoking them all at shutdown.
while(pages.size()>0)
{
log.info("Currently Active Threads: "+Thread.activeCount());
log.info("Pages Found in the Iteration "+j+": "+pages.size());
if(fjp.isShutdown())
{
fjp=new ForkJoinPool(Runtime.getRuntime().availableProcessors()*procnum);
}
i=0;
//if asked to generate a hash, due this first
if(getHash==true){
log.info("Generating Hash");
int s=pages.size();
while(i<s){
String withhash=null;
String str=pages.get(0);
if(str != null){
jmap=Json.read(str).asJsonMap();
jmap.put("offenderhash",Json.read(genHash(jmap.get("offenderhash").asString()+i)));
for(String k:jmap.keySet()){
withhash=(withhash==null)?"{\""+k+"\":\""+jmap.get(k).asString()+"\"":withhash+",\""+k+"\":\""+jmap.get(k).asString()+"\"";
}
if(withhash != null){
withhash+=",}";
}
pages.remove(0);
pages.add((pages.size()-1), withhash);
i++;
}
}
i=0;
}
if(singlepats != null)
{
log.info("Found Singlepats");
for(String row:pages)
{
String str=row;
str=str.replaceAll("\t|\r|\r\n|\n","");
jmap=Json.read(str).asJsonMap();
if(singlepats.containsKey("table"))
{
if(fjp.isShutdown())
{
fjp=new ForkJoinPool((Runtime.getRuntime().availableProcessors()*procnum));
}
fjp=new ForkJoinPool((Runtime.getRuntime().availableProcessors()*procnum));
if(jmap.get(column)!=null)
{
if(test){
System.out.println("//////////////////////HTML////////////////////////\n"+jmap.get(column).asString()+"\n///////////////////////////////END///////////////////////////\n\n");
}
if(mustcontain != null)
{
if(jmap.get(column).asString().contains(mustcontain))
{
if(cannotcontain != null)
{
if(jmap.get(column).asString().contains(cannotcontain)==false)
results.add(fjp.submit(new ParsePage(replacementPattern,singlepats.get("table"),jmap.get(column).asString().replaceAll("\\s\\s", " "),singlepats, Calendar.getInstance().getTime().toString(), jmap.get("offenderhash").asString())));
}
else
{
results.add(fjp.submit(new ParsePage(replacementPattern,singlepats.get("table"),jmap.get(column).asString().replaceAll("\\s\\s", " "),singlepats, Calendar.getInstance().getTime().toString(), jmap.get("offenderhash").asString())));
}
}
}
else if(cannotcontain != null)
{
if(jmap.get(column).asString().contains(cannotcontain)==false)
{
results.add(fjp.submit(new ParsePage(replacementPattern,singlepats.get("table"),jmap.get(column).asString().replaceAll("\\s\\s", " "),singlepats, Calendar.getInstance().getTime().toString(), jmap.get("offenderhash").asString())));
}
}
else
{
results.add(fjp.submit(new ParsePage(replacementPattern,singlepats.get("table"),jmap.get(column).asString().replaceAll("\\s\\s", " "),singlepats, Calendar.getInstance().getTime().toString(), jmap.get("offenderhash").asString())));
}
}
}
i++;
if(((i%commit_size)==0 & i != 0) | i==pages.size() |pages.size()==1 & singlepats != null)
{
log.info("Getting Regex Results");
log.info("Shutdown");
try {
fjp.awaitTermination(termtime, TimeUnit.MILLISECONDS);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
fjp.shutdown();
while(fjp.isTerminated()==false)
{
try{
Thread.sleep(5);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
for(Future<String> r:results)
{
try {
add=r.get();
if(add.contains("No Data")==false)
{
parsedrows.add(add);
}
add=null;
if(r.isDone()==false)
{
r.cancel(true);
}
if(fjp.getActiveThreadCount()>0 && fjp.getRunningThreadCount()>0)
{
fjp.shutdownNow();
}
fjp=new ForkJoinPool(Runtime.getRuntime().availableProcessors()*procnum);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
results=new ArrayList<ForkJoinTask<String>>();
if(parsedrows.size()>=commit_size)
{
if(parsedrows.size()>=SPLITSIZE)
{
sendToDb(parsedrows,true);
}
else
{
sendToDb(parsedrows,false);
}
parsedrows=new ArrayList<String>();
}
//hint to the gc in case it actually pays off (think if i were a gambling man)
System.gc();
Runtime.getRuntime().gc();
}
}
}
log.info("REMAINING ROWS TO COMMIT "+parsedrows.size());
log.info("Rows Left"+parsedrows.size());
if(parsedrows.size()>0)
{
if(parsedrows.size()>=SPLITSIZE)
{
sendToDb(parsedrows,true);
}
else
{
sendToDb(parsedrows,false);
}
parsedrows=new ArrayList<String>();
}
records+=i;
i=0;
//Query for more records to parse
It looks like you're making a new ForkJoinPool for every result. What you really want to do is make a single ForkJoinPool that all your tasks will share. Extra pools won't make extra parallelism available, so one should be fine. When you get a task that is ready to run take your fjp and call fjp.execute(ForkJoinTask) or ForkJoinTask.fork() if you're in a task already.
Making multiple pools seems like a bookkeeping nightmare. Try to get away with just one that's shared.
You are probably using join() in Java7. Join doesn't work. It requires a context switch and Java programs can't do a context switch so the framework creates "continuation threads" to keep moving. I detailed that problem several years ago in this article: ForkJoin Clamamity
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.