180 likes | 284 Vues
Learn why it's crucial to cleanly terminate threads in Java applications to prevent deadlocks and inconsistent states. Discover best practices and the cooperative protocol for thread cancellation and interrupting long waits effectively.
E N D
NeverEnds • (at least) two threads are created: • first thread is main thread, executes main() • second thread is t • main() thread terminates almost immediately. • t never terminates - loops forever • program will never terminate • process only terminates when all of its threads have terminated • Runnable based thread terminates when run() does
t.stop()? • No JAVA interface to shutting down threads from the outside • no way to invoke t.stop() from main
t.stop()? • assume Java allows one thread to stop another • assume while T1 calls T2.stop(), T2 holds some locks and is in the middle of changing the internal state of some object protected by these locks. • if locks are not released whenT2 is stopped - deadlock in the future • if locks are immediately released the object which T2 was working on is in inconsistent state
introduce a new Exception? • introduce a new exception – ThreadDeath • calls to stop() throwsThreadDeathto the thread, interrupting the thread's current execution. • good in theory but impractical and dangerous: • ThreadDeath exception can be thrown anywhere! examine all code, take care of cleanup prior to terminating thread • ThreadDeath exception can be thrown even while we are cleaning after a previous ThreadDeathexception
How to terminate threads cleanly? • use a variable in Thread object that indicates someone requested this thread to stop • thread object checks this variable at regular intervals in run() method • when it is safe to do so • determine whether it accepts to stop (return from run) or not
How to terminate threads cleanly? • thread cancellation is a cooperative protocol: • one thread asks another one to stop • receiving thread can accept or reject request
How to interrupt long waits? • Threads may sometime be stopped for a long period of time. Threads may: • blocked waiting to enter synchronize block • sleep() • wait() • join() • perform IO
interrupted() • Sometimes, when we want to tell a thread T that it needs to stop • T may not notice our request for some time, since T's execution is currently stopped • interrupted status - internal flag to every thread : • interrupt() - flag may be set by any other thread • Thread.isInterrupted() - flag may be checked and cleared
interrupted flag • If Thread T is in • Sleep() • wait() • join() • If thread, D calls T.interrupt(): • InterruptedException will be thrown to T • interrupted status of Tis cleared
interrupted flag • IfT is performing IO, using an interruptible channel: • channel will be closed • T's interrupt status will be set • ClosedByInterruptException will be thrown to T
interrupted flag • IfT is waiting for a Selector to return • T's interrupt status will be set • call to the selector will return.
interrupted flag • If none of the previous conditions holds then 's interrupt status will be set.
interrupt mechanism is used in conjunction with the methods mentioned above