デッドロックの発生をシミュレート--哲学者の食事問題を演繹する

4903 ワード

1 じっと見つめる
一般的なデッドロック形式:スレッド1がリソースR 1を占有し、リソースR 1上のロックを保持し、リソースR 2のロックを待っている場合.一方、スレッド2は、リソースR 2を占有しており、リソースR 2上のロックを保持しているが、リソースR 1上のロックを待っている.2つのスレッドが自分が占有しているリソースロックを解放せず、相手のリソース上のロックを申請した場合、申請が到着しないと待つしかなく、永遠に待つしかありません.
二 実戦
1 コード#コード#
public class DeadLockDemo
{
    /** knife  */
    private static String knife = "  "; //    
    /** fork  */
    private static String fork = "  ";  //    

    public static void main(String[] args)
    {
        DaemonThread daemonTh = new DaemonThread();
        Thread newDaemon = new Thread(daemonTh);
        newDaemon.setDaemon(true);
        newDaemon.start();

        new DeadLockDemo().deadLock();
    }

    private void deadLock()
    {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run()
            {
                synchronized (knife) {
                    System.out.println(Thread.currentThread().getName() + "   " + knife + ",   " + fork + "......");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (fork) {
                        System.out.println(Thread.currentThread().getName() + "    " + fork + ",   ...");
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (fork) {
                    System.out.println(Thread.currentThread().getName() + "   " + fork + ",   " + knife + "......");
                    synchronized (knife) {
                        System.out.println(Thread.currentThread().getName() + "    " + knife + ",   ...");
                    }
                }
            }
        });

        t1.start();
        t2.start();
    }
}
class DaemonThread implements Runnable
{
    @Override
    public void run()
    {
        while(true)
        {
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("    :       ...");
        }
    }
}

2 うんてん
Thread-1     ,     ......
Thread-2     ,     ......
    :       ...
    :       ...
    :       ...
    :       ...
    :       ...

三 デッドロックの予防
1 解決策
スレッドAとBが先にナイフを持ち、フォークを持つように規定すれば、デッドロックは発生しません.
2 コード#コード#
public class DeadLockDemo
{
    /** knife  */
    private static String knife = "  "; //    
    /** fork  */
    private static String fork = "  ";  //    

    public static void main(String[] args)
    {
        DaemonThread daemonTh = new DaemonThread();
        Thread newDaemon = new Thread(daemonTh);
        newDaemon.setDaemon(true);
        newDaemon.start();

        new DeadLockDemo().deadLock();
    }

    private void deadLock()
    {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run()
            {
                synchronized (knife) {
                    System.out.println(Thread.currentThread().getName() + "   " + knife + ",   " + fork + "......");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (fork) {
                        System.out.println(Thread.currentThread().getName() + "    " + fork + ",   ...");
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (knife) {
                    System.out.println(Thread.currentThread().getName() + "   " + knife + ",   " + fork + "......");
                    synchronized (fork) {
                        System.out.println(Thread.currentThread().getName() + "    " + fork + ",   ...");
                    }
                }
            }
        });

        t1.start();
        t2.start();
    }
}
class DaemonThread implements Runnable
{
    @Override
    public void run()
    {
        while(true)
        {
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("    :       ...");
        }
    }
}

3 うんてん
Thread-1     ,     ......
    :       ...
    :       ...
Thread-1      ,   ...
Thread-2     ,     ......
Thread-2      ,   ...