Maison  >  Questions et réponses  >  le corps du texte

java - 多线程死锁测试

package test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * Created by rhwayfun on 16-4-3.
 */
public class ThreadTest {

    private static DateFormat format = new SimpleDateFormat("HH:mm:ss");

    public synchronized void tryOther(ThreadTest other) throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " enter tryOther method at " + format.format(new Date()));      
        System.out.println(Thread.currentThread().getName() + " tryOther method is about to invoke other method at " + format.format(new Date()));
        other.other();
    }

    public synchronized void other() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " enter other method atatatatat " + format.format(new Date()));
    }

    public static void main(String[] args) throws InterruptedException {
        final ThreadTest d1 = new ThreadTest();
        final ThreadTest d2 = new ThreadTest();

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    d1.tryOther(d2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "threadA");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    d2.tryOther(d1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "threadB");

        t1.start();
        //让threadA先运行一秒
        TimeUnit.SECONDS.sleep(1);
        t2.start();

    }
}

如上,随便找的产生死锁的代码,问题:
TimeUnit.SECONDS.sleep(1);加上这行后,不存在死锁问题。sleep并不释放锁,为何这边死锁情况会消失。
输出结果为:
threadA enter tryOther method at 15:37:39
threadA tryOther method is about to invoke other method at 15:37:39
threadA enter other method atatatatat 15:37:39
threadB enter tryOther method at 15:37:40
threadB tryOther method is about to invoke other method at 15:37:40
threadB enter other method atatatatat 15:37:40

注掉这行,正常死锁。
输出结果为:
threadB enter tryOther method at 15:37:10
threadA enter tryOther method at 15:37:10
threadB tryOther method is about to invoke other method at 15:37:10
threadA tryOther method is about to invoke other method at 15:37:10

阿神阿神2742 Il y a quelques jours686

répondre à tous(3)je répondrai

  • 大家讲道理

    大家讲道理2017-04-18 10:56:48

    Le thread A obtient le verrou tryOther, mais il doit toujours obtenir l'autre verrou
    Le thread B obtient le verrou tryOther, mais il doit toujours obtenir l'autre verrou
    Il est possible que A vient de se libérer. le verrou et B viennent de libérer tryAutre
    Pour le moment, mais ils veulent tous acquérir le verrou de l'autre en même temps, personne ne laissera personne se bloquer
    La solution est d'empêcher les deux threads de s'emparer du verrou. deuxième verrouillage en même temps. Laissez A s'arrêter pendant un moment. Oui
    Mais si vous ajustez le temps au niveau de la nanoseconde et essayez plusieurs fois, un blocage se produira
    Ceci n'est pas recommandé pour éviter un blocage. la concurrence est élevée.

    répondre
    0
  • 阿神

    阿神2017-04-18 10:56:48

    Les deux parties se battent pour le même verrou, il n'y aura pas d'impasse

    répondre
    0
  • PHPz

    PHPz2017-04-18 10:56:48

    J'ai soudain compris pourquoi et j'étais trop paresseux pour supprimer le message. J'écrirai mon opinion. Si je me trompe, corrigez-moi
    Quand il n'y a pas de veille, le thread a démarre, termine la méthode tryOther, libère le verrou et exécute l'autre méthode à ce moment-là. obtient le verrou et exécute la méthode tryOther,
    A ce moment, les ressources requises par a dans l'autre méthode sont verrouillées par le thread b Après avoir exécuté tryOther, b doit obtenir les ressources de a, ce qui entraîne une impasse.

    Après avoir ajouté le sommeil. Lorsqu'a exécute la méthode tryOther pour libérer le verrou, le thread b n'est pas exécuté à ce moment-là et l'autre verrou est obtenu avec succès à ce moment-là. Le thread b est exécuté après 2 s,
    aucun environnement de blocage.

    répondre
    0
  • Annulerrépondre