The Thread class contains constructors and methods for creating and operating on threads. Thread is a subclass of Object that implements the Runnable interface. There are many methods in Thread Class but some of them are deprecated as of JDK 1.1. In this article, we will understand the reason behind it.
Deprecated methods are those that are no longer considered important and should not be utilized because they may be removed from their class. Classes evolve over time, leading their APIs to alter, resulting in deprecation. Attributes change, methods are renamed, and new ones are added. To help developers shift from the old API to the new one, deprecated classes and methods are marked @deprecated in documentation comments.
Why deprecated ??
Thread.stop() is being phased out due to its inherent risk. When you stop a thread, it unlocks all the monitors it has locked. Other threads might see these objects in an inconsistent state if any of the objects previously protected by these monitors were in an inconsistent state.
Threads acting on damaged objects can act erratically, whether consciously or unconsciously. ThreadDeath, unlike other uncontrolled exceptions, silently kills threads, leaving the user with no warning that the program may be corrupted. After the damage has occurred, the corruption may appear at an unpredicted moment. Also, killing a thread will create a problem while working with DBMS – JDBC in a multithreaded environment.
Thread.suspend() is deprecated because it is inherently deadlock-prone. As a result, Thread.resume() must be deprecated as well. When the target thread is suspended, it holds a lock on the monitor protecting a crucial system resource, and no other thread may access it until the target thread is resumed. Deadlock occurs if the thread that would restart the target thread tries to lock this monitor before invoking resume().
Example of possible deadlock from using these deprecated methods:
Java
// This class contains an integer array & // Threads set the element's value for this array class NumVal { private int num[] = null ; boolean valueSet = false ; int i = 0 ; NumVal() { // Creating integer array of 10 elements num = new int [ 10 ]; } // method to set the values in the array public void setVal( int n) { if (i < 9 ) { System.out.println( "Putting value " + n + " in the NumVal Array" ); num[i] = n; i++; } } // method to get the values from the array public int getVal() { if (i >= 0 ) { System.out.println( "Giving n = " + num[i]); i--; return num[i + 1 ]; } else { return - 1 ; } } } // Creating Our Thread Class class MyThread extends Thread { // MyThread want mutually exclusive // lock on the object // referred by: NumObjToSetVal NumVal NumObjToSetVal = null ; // Constructor public MyThread(String threadName, NumVal numV) { super (threadName); NumObjToSetVal = numV; } public void run() { // Only 1 thread at a time an access the object // referred by : NumObjToSetVal synchronized (NumObjToSetVal) { int n = 0 ; while (n < 5 ) { System.out.println( "THREAD NAME : " + Thread.currentThread().getName()); n++; NumObjToSetVal.setVal(n); try { // Make the thread sleep for 100 ms Thread.sleep( 100 ); System.out.println( Thread.currentThread().getName() + "is awake now" ); } catch (Exception e) { System.out.println( "Exception Caught" ); } // If n is 2 , we suspend this thread if (n == 2 ) { // suspend the thread, now this thread // will release lock on NumObjToSetVal // only when resume() method is called // on this thread, thread will go in // waiting state Thread.currentThread().suspend(); } } } } } public class Main { public static void main(String[] args) { // TODO Auto-generated method stub NumVal v = new NumVal(); // Creating thread 1 that want exclusive lock on // object referred by v MyThread thread1 = new MyThread( "Thread1 " , v); // Creating thread 2 that want exclusive lock on // object referred by v // thread1 is not going to release lock on Object // referred by v until resume() method is not called // and for acquiring lock on v Object refred by v , // thread1 must have released lock on Object // referred by v, if lock is not released, thread2 // will keep on waiting for thread1 to release lock // onbject referred by v & deadlock will be formed MyThread thread2 = new MyThread( "Thread2 " , v); // starting both threads thread1.start(); thread2.start(); for ( int i = 500 ; i <= 501 ; i++) { System.out.println( "Main Thread " + i); } } } |
Output:
THREAD NAME : Thread1 Putting value 1 in the NumVal Array Main Thread 500 Main Thread 501 Thread1 is awake now THREAD NAME : Thread1 Putting value 2 in the NumVal Array Thread1 is awake now //Deadlock is created & hence no output after this
Explanation: We created 2 threads: thread1 & thread2. Both want to acquire a lock on the NumVal object referred to by ‘v’ reference.
As we start both the threads by calling the start() method, the run() method will execute whenever the thread gets CPU. Thread1 gets CPU & when the value of n is 2 in its run method, the thread is suspended. Thread1 is not going to release lock on Object referred by ‘v’ until resume() is called on it.
For thread2 to acquire a lock on v Object referred by ‘v’, thread1 must have released the lock on Object referred by ‘v’. Here the lock here is not released, thread2 will keep on waiting for thread1 to release the lock on the object referred by ‘v’ & a deadlock will be formed.
So, you have always call resume() on a thread (at any time) whenever you call suspend() method on the same thread.