Latest web development tutorials

Esempi Java - Deadlock e soluzione

Esempi di Java Esempi di Java

Deadlock è una situazione: una pluralità di fili sono bloccati, uno o tutti loro sono in attesa di una risorsa per essere rilasciato. Poiché il filo bloccato indefinitamente, quindi il programma non può essere terminato normalmente.

Quattro condizioni necessarie java Deadlock:

  • 1, uso esclusivo, che è, quando la risorsa è un filo (possesso), altri thread non possono essere utilizzati
  • 2, non può cogliere il richiedente risorsa non può essere costretto a cogliere le risorse dalle mani del possesso delle risorse, risorse, risorse possono essere rilasciati solo dagli occupanti iniziativa.
  • 3, le richieste, e sostenendo che, quando il richiedente delle risorse, mentre la richiesta di risorse aggiuntive per mantenere il possesso della risorsa originale.
  • 4, aspetta ciclo, cioè, c'è una coda: P1 P2 occupa risorse, P2 e P3 possesso delle risorse, la quota P1 P3 delle risorse. Così formando un ciclo di attesa.

Quando sono soddisfatte queste quattro condizioni, quindi una situazione di stallo. Naturalmente, se il caso di una situazione di stallo per rompere qualsiasi di queste condizioni, si può lasciare che la situazione di stallo scomparire. Utilizzare il seguente codice per simulare ciò che Java deadlock prodotti.

Soluzione al problema stallo è: uno è sincronizzato, uno è quello di utilizzare i blocchi espliciti per Lock.

Se l'uso improprio di serrature, e lo schermo allo stesso tempo quando si desidera bloccare più oggetti, ci sarà una situazione di stallo, come segue:

/*
 author by w3cschool.cc
 LockTest.java
 */

import java.util.Date;

public class LockTest {
   public static String obj1 = "obj1";
   public static String obj2 = "obj2";
   public static void main(String[] args) {
      LockA la = new LockA();
      new Thread(la).start();
      LockB lb = new LockB();
      new Thread(lb).start();
   }
}
class LockA implements Runnable{
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockA 开始执行");
         while(true){
            synchronized (LockTest.obj1) {
               System.out.println(new Date().toString() + " LockA 锁住 obj1");
               Thread.sleep(3000); // 此处等待是给B能锁住机会
               synchronized (LockTest.obj2) {
                  System.out.println(new Date().toString() + " LockA 锁住 obj2");
                  Thread.sleep(60 * 1000); // 为测试,占用了就不放
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
class LockB implements Runnable{
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockB 开始执行");
         while(true){
            synchronized (LockTest.obj2) {
               System.out.println(new Date().toString() + " LockB 锁住 obj2");
               Thread.sleep(3000); // 此处等待是给A能锁住机会
               synchronized (LockTest.obj1) {
                  System.out.println(new Date().toString() + " LockB 锁住 obj1");
                  Thread.sleep(60 * 1000); // 为测试,占用了就不放
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Il codice di cui sopra viene eseguito in uscita è:

Tue May 05 10:51:06 CST 2015 LockB 开始执行
Tue May 05 10:51:06 CST 2015 LockA 开始执行
Tue May 05 10:51:06 CST 2015 LockB 锁住 obj2
Tue May 05 10:51:06 CST 2015 LockA 锁住 obj1

A questo punto morto.

Per risolvere questo problema, non utilizzare per visualizzare le serrature, usiamo semafori per controllare.

Semaforo in grado di controllare il numero di thread possono accedere alle risorse, specifichiamo qui può essere solo un accesso filo, si fa un blocco simile. Il semaforo può specificare un timeout per ottenere, possiamo secondo il time-out, fare un trattamento supplementare.

Il caso non può ottenere, il generale è quello di ripetere il tentativo, o specificare il numero di tentativi, si può uscire immediatamente.

Guardate il seguente codice:

/*
 author by w3cschool.cc
 UnLockTest.java
 */

import java.util.Date;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class UnLockTest {
   public static String obj1 = "obj1";
   public static final Semaphore a1 = new Semaphore(1);
   public static String obj2 = "obj2";
   public static final Semaphore a2 = new Semaphore(1);

   public static void main(String[] args) {
      LockAa la = new LockAa();
      new Thread(la).start();
      LockBb lb = new LockBb();
      new Thread(lb).start();
   }
}
class LockAa implements Runnable {
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockA 开始执行");
         while (true) {
            if (UnLockTest.a1.tryAcquire(1, TimeUnit.SECONDS)) {
               System.out.println(new Date().toString() + " LockA 锁住 obj1");
               if (UnLockTest.a2.tryAcquire(1, TimeUnit.SECONDS)) {
                  System.out.println(new Date().toString() + " LockA 锁住 obj2");
                  Thread.sleep(60 * 1000); // do something
               }else{
                  System.out.println(new Date().toString() + "LockA 锁 obj2 失败");
               }
            }else{
               System.out.println(new Date().toString() + "LockA 锁 obj1 失败");
            }
            UnLockTest.a1.release(); // 释放
            UnLockTest.a2.release();
            Thread.sleep(1000); // 马上进行尝试,现实情况下do something是不确定的
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
class LockBb implements Runnable {
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockB 开始执行");
         while (true) {
            if (UnLockTest.a2.tryAcquire(1, TimeUnit.SECONDS)) {
               System.out.println(new Date().toString() + " LockB 锁住 obj2");
               if (UnLockTest.a1.tryAcquire(1, TimeUnit.SECONDS)) {
                  System.out.println(new Date().toString() + " LockB 锁住 obj1");
                  Thread.sleep(60 * 1000); // do something
               }else{
                  System.out.println(new Date().toString() + "LockB 锁 obj1 失败");
               }
            }else{
               System.out.println(new Date().toString() + "LockB 锁 obj2 失败");
            }
            UnLockTest.a1.release(); // 释放
            UnLockTest.a2.release();
            Thread.sleep(10 * 1000); // 这里只是为了演示,所以tryAcquire只用1秒,而且B要给A让出能执行的时间,否则两个永远是死锁
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Esempi della struttura di uscita codice di cui sopra:

Tue May 05 10:59:13 CST 2015 LockA 开始执行
Tue May 05 10:59:13 CST 2015 LockB 开始执行
Tue May 05 10:59:13 CST 2015 LockB 锁住 obj2
Tue May 05 10:59:13 CST 2015 LockA 锁住 obj1
Tue May 05 10:59:14 CST 2015LockB 锁 obj1 失败
Tue May 05 10:59:14 CST 2015LockA 锁 obj2 失败
Tue May 05 10:59:15 CST 2015 LockA 锁住 obj1
Tue May 05 10:59:15 CST 2015 LockA 锁住 obj2

Esempi di Java Esempi di Java