join() waiting forever when exception occurs, jvm shutdown hook not working - multithreading

I am trying to shutdown the application, whenever any Fatal
Error/Exception comes but before shut down the application my current
thread/task should complete, so I have written mainThread.join()
inside run(), its working fine when there is no exception. But whenever my
doTask() throwing exception that time join() waiting forever.
public class POC
{
public void doTask() throws Exception
{
throw new Exception("Fatal Error");
//throw new Exception("Fatal Error"); By commenting working fine.
}
public static void main(String[] args)
{
POC ob = new POC();
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
try
{
System.out.println("Join() Start");
mainThread.join();
System.out.println("Join() End"); //Why this is not printing?
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
try
{
System.out.println("Before doTask()");
ob.doTask(); //User Defined Run()
System.out.println("After doTask()");
}
catch (Exception ex) // FATAL
{
System.err.println("Exception : " + ex.getLocalizedMessage());
System.exit(-1);
}
}
}
OutPut : 0
Before Run()
Exception : Fatal Error
Join() Start
Why System.out.println("Join() End"); is not printing?

You have a simple deadlock.
When you throw an exception, exception handler call System.exit(-1), which is blocking, see javadoc:
Terminates the currently running Java virtual machine by initiating its shutdown sequence
...
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered #addShutdownHook shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish.
So main thread is waiting in System#exit call until all shutdown hook will be finished and your only shutdown hook blocks and waits until main thread will finish (which is waiting in System#exit ... GOTO 1).

Related

Execution of a thread after it got interrupted

A thread is executing task to print numbers from 0 to n, and sleeps for 4000 ms after every print statement. Somewhere in the middle thread gets interrupted. Now when the same thread starts its execution, where will it start from , will it start printing the numbers from 0 to n again, or it will print numbers from where it got interrupted.
In both cases what are the reasons and how it is being handled?
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest);
thread.start();
thread.interrupt();
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt();
Thread.sleep(4000);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println(Thread.interrupted());
}
}
Calling a interrupt() on a thread object can only suggest thread to stop. It is not guarantee that the thread will stop.
It completely depends on the implementation of run() method of thread.
In your case in run() you are catching the InterruptedException and you are printing the exception trace but not stopping the thread. Thats why thread will never stop on InterruptedException and continue the execution.
It may look like thread is getting stopped(by seeing exception trace) when see the output on console.
Refer interrupt interrupted isinterrupted in Java
All Thread.currentThread().interrupt() does is update the value of field interrupted to true.
Let's see the program's flow and how the interrupted field is assigned values:
public class Main {
public static void main(String[] args) throws InterruptedException {
SleepTest sleepTest = new SleepTest();
Thread thread = new Thread(sleepTest, "Sub Thread"); // Give a name to this thread
thread.start(); // main thread spawns the "Sub Thread". Value of "interrupted" - false
thread.interrupt(); // called by main thread. Value of "interrupted" - true
}
}
public class SleepTest implements Runnable{
static int sleep = 10;
public void run(){
System.out.println(Thread.currentThread().getName()+" "+Thread.interrupted()); // prints "Sub Thread true"
for (int i =0; i<10; i++){
System.out.println(i);
try {
Thread.currentThread().interrupt(); // no matter what value is for interrupted, it is assigned the value "true"
Thread.sleep(4000); // Can't call sleep with a "true" interrupted status. Exception is thrown. Note that, when the exception is thrown, the value of interrupted is "reset", i.e., set to false
} catch (InterruptedException exception) {
exception.printStackTrace(); // whatever
}
System.out.println(Thread.interrupted()); // returns the value of interrupted and resets it to false
}
}
To answer
where will it start from , will it start printing the numbers from 0
to n again, or it will print numbers from where it got interrupted.
Calling interrupt will not cause make it start over because all it is doing at this call is set value interrupted to false (and not modifying anything else).

javamail idle stops triggering messagesAdded after a while, thread locked

I'm developing an android app that receives and processes mail messages. The app must be connected to an IMAP server and keep the connection alive, so it can see and process new mail messages instantly (mails contains json data from a mail api server). The app have two modes, manual and live connection. Here is some of my code:
class Idler {
Thread th;
volatile Boolean isIdling=false;
boolean shouldsync=false;//we need to see if we have unseen mails
Object idleLock;
Handler handler=new Handler();
IMAPFolder inbox;
public boolean keppAliveConnection;//keep alive connection, or manual mode
//This thread should keep the idle connection alive, or in case it's set to manual mode (keppAliveConnection=false) get new mail.
Thread refreshThread;
synchronized void refresh()
{
if(isIdling)//if already idling, just keep connection alive
{
refreshThread =new Thread(new Runnable() {
#Override
public void run() {
try {
inbox.doCommand(new IMAPFolder.ProtocolCommand() {
#Override
public Object doCommand(IMAPProtocol protocol) throws ProtocolException {
//Why not noop?
//any call to IMAPFolder.doCommand() will trigger waitIfIdle, this
//issues a "DONE" command and waits for idle to return(ideally with a DONE server response).
// So... I think NOOP is unnecessary
//protocol.simpleCommand("NOOP",null); I'm not issuing noop due to what I said ^
//PD: if connection was broken, then server response will never arrive, and idle will keep running forever
//without triggering messagesAdded event any more :'( I see any other explanation to this phenomenon
return null;
}
});
} catch (MessagingException e) {
e.printStackTrace();
}
}
},"SyncThread");
refreshThread.start();
}
else
{
getNewMail();//If manual mode keppAliveConnection=false) get the new mail
}
}
public Idler()
{
th=new Thread(new Runnable() {
#SuppressWarnings("InfiniteLoopStatement")
#Override
public void run() {
while (true)
{
try {
if(refreshThread !=null && refreshThread.isAlive())
refreshThread.interrupt();//if the refresher thread is active: interrupt. I thing this is not necessary at this point, but not shure
initIMAP();//initializes imap store
try {
shouldsync=connectIMAP()||shouldsync;//if was disconnected or ordered to sync: needs to sync
}
catch (Exception e)
{
Thread.sleep(5000);//if can't connect: wait some time and throw
throw e;
}
shouldsync=initInbox()||shouldsync;//if inbox was null or closed: needs to sync
if(shouldsync)//if needs to sync
{
getNewMail();//gets new unseen mail
shouldsync=false;//already refreshed, clear sync "flag"
}
while (keppAliveConnection) {//if sould keep idling "forever"
synchronized (idleLock){}//MessageCountListener may be doing some work... wait for it
isIdling = true; //set isIdling "flag"
handler.removeCallbacksAndMessages(null);//clears refresh scheduled tasks
handler.postDelayed(new Runnable() {
#Override
public void run() {
refresh();
}
},1200000);//Schedule a refresh in 20 minutes
inbox.idle();//start idling
if(refreshThread !=null && refreshThread.isAlive())
refreshThread.interrupt();//if the refresher thread is active: interrupt. I thing this is not necessary at this point, but not shure
handler.removeCallbacksAndMessages(null);//clears refresh scheduled tasks
isIdling=false;//clear isIdling "flag"
if(shouldsync)
break;//if ordered to sync... break. The loop will handle it upstairs.
synchronized (idleLock){}//MessageCountListener may be doing some work... wait for it
}
}
catch (Exception e) {
//if the refresher thread is active: interrupt
//Why interrupt? refresher thread may be waiting for idle to return after "DONE" command, but if folder was closed and throws
//a FolderClosedException, then it could wait forever...., so... interrupt.
if (refreshThread != null && refreshThread.isAlive())
refreshThread.interrupt();
handler.removeCallbacksAndMessages(null);//clears refresh scheduled tasks
}
}
}
},"IdlerThread");
th.start();
}
private synchronized void getNewMail()
{
shouldsync=false;
long uid=getLastSeen();//get last unprocessed mail
SearchTerm searchTerm=new UidTerm(uid,Long.MAX_VALUE);//search from las processed message to the las one.
IMAPSearchOperation so=new IMAPSearchOperation(searchTerm);
try {
so.run();//search new messages
final long[] is=so.uids();//get unprocessed messages count
if (is.length > 0) {//if some...
try {
//there are new messages
IMAPFetchMessagesOperation fop=new IMAPFetchMessagesOperation(is);
fop.run();//fetch new messages
if(fop.messages.length>0)
{
//process fetched messages (internally sets the last seen uid value & delete some...)
processMessages(fop.messages);
}
inbox.expunge();//expunge deleted messages if any
}
catch (Exception e)
{
//Do something
}
}
else
{
//Do something
}
}
catch (Exception e)
{
//Do something
}
}
private synchronized void initIMAP()
{
if(store==null)
{
store=new IMAPStore(mailSession,new URLName("imap",p.IMAPServer,p.IMAPPort,null,p.IMAPUser,p.IMAPPassword));
}
}
private boolean connectIMAP() throws MessagingException {
try {
store.connect(p.IMAPServer, p.IMAPPort, p.IMAPUser, p.IMAPPassword);
return true;
}
catch (IllegalStateException e)
{
return false;
}
}
//returns true if the folder was closed or null
private synchronized boolean initInbox() throws MessagingException {
boolean retVal=false;
if(inbox==null)
{//if null, create. This is called after initializing store
inbox = (IMAPFolder) store.getFolder("INBOX");
inbox.addMessageCountListener(countListener);
retVal=true;//was created
}
if(!inbox.isOpen())
{
inbox.open(Folder.READ_WRITE);
retVal=true;//was oppened
}
return retVal;
}
private MessageCountListener countListener= new MessageCountAdapter() {
#Override
public void messagesAdded(MessageCountEvent ev) {
synchronized (idleLock)
{
try {
processMessages(ev.getMessages());//process the new messages, (internally sets the last seen uid value & delete some...)
inbox.expunge();//expunge deleted messajes if any
} catch (MessagingException e) {
//Do something
}
}
}
};
}
The problem is: Sometimes when the user is refreshing or the app auto-refreshes, in the Alive Connection mode, one or both of this conditions keeps my app from getting new messages. This is from the javamail source code.
1: The IdlerThread enters monitor state in:
//I don't know why sometimes it enters monitor state here.
private synchronized void throwClosedException(ConnectionException cex)
throws FolderClosedException, StoreClosedException {
// If it's the folder's protocol object, throw a FolderClosedException;
// otherwise, throw a StoreClosedException.
// If a command has failed because the connection is closed,
// the folder will have already been forced closed by the
// time we get here and our protocol object will have been
// released, so if we no longer have a protocol object we base
// this decision on whether we *think* the folder is open.
if ((protocol != null && cex.getProtocol() == protocol) ||
(protocol == null && !reallyClosed))
throw new FolderClosedException(this, cex.getMessage());
else
throw new StoreClosedException(store, cex.getMessage());
}
2: The "refresherThread" enters wait state in:
void waitIfIdle() throws ProtocolException {
assert Thread.holdsLock(messageCacheLock);
while (idleState != RUNNING) {
if (idleState == IDLE) {
protocol.idleAbort();
idleState = ABORTING;
}
try {
// give up lock and wait to be not idle
messageCacheLock.wait();//<-----This is the line is driving me crazy.
} catch (InterruptedException ex) { }
}
}
As one of both of this threads "stops" running (wait & monitor state) my app is useless when reach this condition. In my country the mobile data network is very unstable, slow & expensive(GSM) So it must be failure resilient and take care about every transferred bit.
I guess the problem arises when the connection silently fails and the refresherThread starts to do its job. It issues a DONE command if idle is active, but, as the connection is gone, when idle tries to throw a FolderClosedException, one or both threads gets locked indefinitely.
So, my question is: Why is this situation arising and how to prevent it? How can I keep the idle loop securely running without getting locked?
I've tried a lot of things till exhaustion with no results.
Here are some threads I've read without getting a solution to my problem. In my country internet is EXTREMELY expensive too, so I can't research as much as I want, nor list all the urls I've visited looking for information.
JavaMail: Keeping IMAPFolder.idle() alive
JavaMail: Keeping IMAPFolder.idle() alive
Javamail : Proper way to issue idle() for IMAPFolder
Please, excuse my english. Any suggestion will be greatly appreciated. I've heard about this site strictness, so please be gentle, I'm new over here.
Be sure to set the timeout properties to make sure you don't hang waiting for a dead connection or server.
Instead of issuing a nop command directly, you should call Folder.isOpen or Folder.getMessageCount; they'll issue the nop command if needed.
If the folder is closed asynchronously (FolderClosedException), you'll need to restart the idle loop.

Why is that Thread interupt method is not breaking its sleep method?

I have this program below
package com;
public class ThreadDemo implements Runnable {
#Override
public void run() {
while(true)
{
try {
System.out.println("Into sleep");
Thread.sleep(1000000000);
System.out.println("Out of sleep");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String args[]) {
ThreadDemo tD = new ThreadDemo();
Thread t1 = new Thread(tD);
t1.start();
t1.interrupt();
}
}
I have started the Thread , and will call its run method and goes into sleep state for the above specified seconds .
i have called t1.interrupt();
This is the screen shot
My question is that why
1.The Thread is not coming out of sleep state ?
Why Into sleep is printed twice ??
You're in a loop:
You're sleeping
Being interrupted and printing the stack trace
Going back to sleep
Never being interrupted again
So it is "coming out of sleep state" (otherwise you wouldn't see the stack trace) - but you're then calling Thread.sleep again.
If you only want to sleep once, get rid of the loop...
1.The Thread is not comng out of sleep state ?
He actually is but
System.out.println("Out of sleep");
is never executed because when you interrupt Thread.sleep(10000); throws a exception and
e.printStackTrace();
is execute instead

Threading in Spring

I'm trying to do some optimization in my code and would like to spawn a thread where I do a time consuming operation. During the implementation of that optimization I was running into an issue which was driving me crazy. I simplified the issue and created a test case for that specific issue: (I'm using SpringJUnit4ClassRunner so the transaction is properly started at the beginning of the testCRUD method)
Could someone help me understand why the foundParent is null in the thread ?
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
(new Thread(
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
})).start();
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
=============================EDITED===================================
As per one comment suggestion, I created a threadManager bean which spawn the thread. Here is the code of the threadManager:
public class ThreadManager {
#Transactional(propagation=Propagation.REQUIRES_NEW)
public void executeTask(String Name, Runnable task) {
(new Thread(task, Name)).start();
}
}
Then in the previous test, instead of staring the thread manually, I just post it in the thread manager like this:
#Autowired private ParentDao parentDao;
#Autowired private ThreadManager threadManager;
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
threadManager.executeTask("BG processing...",
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
});
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Unfortunately this doesn't work either !!! :-(
The transaction context is bound to the thread. So the code in the spawned thread doesn't run in the same transaction context as the code in the initial thread. So, due to transaction isolation (the I in ACID), the spawned thread doesn't see what the initial thread's transaction is inserting in the database.
You can bind Spring transaction to a new thread, to run transactions & Hibernate/JPA access in it. But this has to be a different TX and JPA/HB session from other threads.
Spring code for OpenSessionInViewFilter, is a reasonable an example of how to bind Hibernate session to Spring's TX management. You can strip this down to fairly minimal code.
See:
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
OpenSessionInViewFilter.doFilterInternal() -- this is where it actually binds it
TransactionSynchronizationManager.bindResource()
TransactionSynchronizationManager.unbindResource()
TransactionSynchronizationManager.getResource()
In one project (IIRC) I wrapped this functionality into a 'ServerThreadHb' class, to setup & save previous thread-bindings on construction -- with a restore() method to be called in a finally block, to restore previous bindings.
For your posted code sample, there isn't much point in running work on a separate thread -- since you synchronously wait for the work to be done. However I assume you were planning to remove that constraint & extend that functionality.

How to cancel a task or terminate the task execution instantly?

I have a windows service developed in C#. On it's Start method I have a initialization such as:
Task _backgroundTask = null;
CancellationTokenSource _backgroundCancellationSource = null;
protected override void OnStart(string[] args)
{
......
_backgroundCancellationSource = new CancellationTokenSource();
CancellationToken token = backgroundCancellationSource.Token;
_backgroundTask = new Task(() => BackgroundFoldersProcessing(token), token, TaskCreationOptions.LongRunning);
.......
}
Now the method BackgroundFoldersProcessing looks like this:
void BackgroundFoldersProcessing(CancellationToken token)
{
while (true)
{
try
{
if (token.IsCancellationRequested)
{
return;
}
DoSomeWork()
}
catch (Exception ex)
{
.........
}
}
}
Now, the Stop method is as follows:
protected override void OnStop()
{
.................
_backgroundCancellationSource.Cancel();
_backgroundTask.Wait();
_backgroundCancellationSource.Dispose();
_backgroundTask.Dispose();
_backgroundTask = null;
_backgroundCancellationSource = null;
.................
}
Now the problem is when I try to stop the service in a middle of processing, the Wait method of _backgroundTask would not stop the service until and unless the DoSomeWork() method inside the BackgroundFoldersProcessing gets completed, the Windows Service would not stop.
Is there any way, though which I can stop the service and the execution of _backgroundTask would be terminated, even though the DoSomeWork() method gets completed/executed or not? I have also tried token.ThrowIfCancellationRequested() in BackgroundFoldersProcessing method, but that also did not worked. I want that whenever I try to Stop the service from Service Control Manager (SCM), the service should be stopped immediately and the __backgroundTask should stop executing the BackgroundFoldersProcessing method and be terminated as well. How can I achieve this?
You can try use ThreadAbortException:
defining the thread:
ThreadStart threadDelegate = new ThreadStart(BackgroundFoldersProcessing);
Thread thread_ = new Thread(threadDelegate);
thread_.Start();
Add catch to BackgroundFoldersProcessing
catch (ThreadAbortException e)
{
return;
}
and when you want to shut it down use:
thread_.Abort();
thread_.Join();
Then when Abort() will be called ThreadAbortException will be thrown.

Resources