¿Por qué los métodos Thread.stop(), Thread.suspend() y Thread.resume() están en desuso después de la versión JDK 1.1?

La clase Thread contiene constructores y métodos para crear y operar en hilos. Thread es una subclase de Object que implementa la interfaz Runnable. Hay muchos métodos en Thread Class, pero algunos de ellos están en desuso a partir de JDK 1.1. En este artículo, entenderemos la razón detrás de esto.

Los métodos en desuso son aquellos que ya no se consideran importantes y no deben utilizarse porque pueden eliminarse de su clase. Las clases evolucionan con el tiempo, lo que lleva a que sus API se alteren, lo que resulta en obsolescencia. Los atributos cambian, los métodos cambian de nombre y se agregan otros nuevos. Para ayudar a los desarrolladores a pasar de la API antigua a la nueva, las clases y los métodos obsoletos se marcan como @obsoletos en los comentarios de la documentación.

¿Por qué en desuso?

Thread.stop() se está eliminando gradualmente debido a su riesgo inherente. Cuando detiene un hilo, desbloquea todos los monitores que ha bloqueado. Otros subprocesos pueden ver estos objetos en un estado incoherente si alguno de los objetos previamente protegidos por estos monitores estaba en un estado incoherente.
Los hilos que actúan sobre los objetos dañados pueden actuar de forma errática, ya sea consciente o inconscientemente. ThreadDeath, a diferencia de otras excepciones no controladas, elimina silenciosamente los subprocesos y deja al usuario sin advertencia de que el programa puede estar dañado. Después de que se ha producido el daño, la corrupción puede aparecer en un momento imprevisto. Además, eliminar un subproceso creará un problema al trabajar con DBMS – JDBC en un entorno de subprocesos múltiples.

Thread.suspend() está en desuso porque es inherentemente propenso a interbloqueos. Como resultado, Thread.resume() también debe quedar obsoleto. Cuando se suspende el subproceso de destino, mantiene un bloqueo en el monitor que protege un recurso crucial del sistema y ningún otro subproceso puede acceder a él hasta que se reanude el subproceso de destino. Se produce un interbloqueo si el subproceso que reiniciaría el subproceso de destino intenta bloquear este monitor antes de invocar resume().

Ejemplo de posible interbloqueo por el uso de estos métodos obsoletos:

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);
        }
    }
}

 
Producción: 

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

Explicación: creamos 2 subprocesos: subproceso1 y subproceso2. Ambos quieren adquirir un bloqueo en el objeto NumVal al que hace referencia la referencia ‘v’. 

Como iniciamos ambos subprocesos llamando al método start(), el método run() se ejecutará cada vez que el subproceso obtenga CPU. Thread1 obtiene CPU y cuando el valor de n es 2 en su método de ejecución, el hilo se suspende. Thread1 no va a liberar el bloqueo en el Objeto referido por ‘v’ hasta que se llame a resume().

Para que subproceso2 adquiera un bloqueo en v Objeto referido por ‘v’, subproceso1 debe haber liberado el bloqueo en Objeto referido por ‘v’. Aquí el bloqueo aquí no se libera, thread2 seguirá esperando que thread1 libere el bloqueo en el objeto referido por ‘v’ y se formará un interbloqueo.

Por lo tanto, siempre ha llamado a resume() en un hilo (en cualquier momento) cada vez que llama al método suspend() en el mismo hilo.

Publicación traducida automáticamente

Artículo escrito por sameekshakhandelwal1712 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *