Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 实现死锁条件_Java_Multithreading - Fatal编程技术网

Java 实现死锁条件

Java 实现死锁条件,java,multithreading,Java,Multithreading,我试图实现死锁条件,但不知何故,我无法让它工作。线程Thread1和Thread2都进入run函数,但根据谁先进入run,只有一个线程进入Sub/Sum。示例:如果Thread2先输入run,它将调用sub(),Thread1从不调用sum()。我还添加了睡眠时间,以便Thread2在调用sum()之前睡眠,Thread1有足够的时间输入sum(),但Thread1从未进入 public class ExploringThreads { public static voi

我试图实现死锁条件,但不知何故,我无法让它工作。线程Thread1和Thread2都进入run函数,但根据谁先进入run,只有一个线程进入Sub/Sum。示例:如果Thread2先输入run,它将调用sub(),Thread1从不调用sum()。我还添加了睡眠时间,以便Thread2在调用sum()之前睡眠,Thread1有足够的时间输入sum(),但Thread1从未进入

    public class ExploringThreads {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            threadexample a1 = new threadexample();
            Thread t1 = new Thread(a1, "Thread1");
            Thread t2 = new Thread(a1,"Thread2");
            t1.start();
            t2.start();
        }
    }
    class threadexample implements Runnable{
        public int a = 10;
        public void run(){
            if(Thread.currentThread().getName().equals("Thread1"))
                sum();
            else if(Thread.currentThread().getName().equals("Thread2"))
                sub();
        }

        public synchronized void sum()
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"In Sum");
            sub();
        }

        public synchronized void sub()
        {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"In Sub");
            sum();
        }
    }

这不是死锁的原因。实际上,这段代码看起来相当安全:-)一次只有一个线程输入sum/sub,因为您使用的是同步的,它在“this”上同步。只有一个“this”,因此两个线程都尝试获取相同的锁

死锁发生,例如,当Thread1有一个锁,Thread2有第二个锁,然后Thread1希望在保持Thread2锁的同时获得Thread2锁,Thread2希望在保持Thread1锁的同时获得Thread1锁

你能做的是:

a) 在“threadexample”类中添加2个用于锁定的对象(顺便说一句,按照惯例,类应以大写开头):

b) 在两个sum/sub方法中删除“synchronized”关键字,而是在每个方法中使用synchronized(){}块。Sum将被同步(sumLock){/*Sum的主体在这里/},sub将被同步(subLock){/sub的主体在这里*/}

在这种情况下,Thread1将进入sum(),获取sumLock并等待。Thread2将进入sub(),获取subLock()并等待。Thread1会醒来,进入sub()并尝试获取subLock,但它被Thread2持有,所以它会等待Thread2释放它。此时,Thread2醒来,进入sum()并尝试获取Thread1持有的sumLock,因此Thread2等待Thread1释放它

这两个线程都不会前进,因为它们中的每一个都在等待另一个线程——这是一个死锁


@编辑:是的,您只有一个“threadexample”实例,Thread1和Thread2都在争夺锁,但当其中一个获得锁时,它将在执行sum/sub或sub/sum后释放锁。例如,假设Thread1是第一个并开始执行sum()。它有锁。在这种情况下,Thread2将不会进入sub(),因为它受到与Thread1相同的锁的保护。Thread1将执行sum(),然后是sub(),然后它将释放锁-->Thread2将进入sub()等等。

如果确实要创建一个人工死锁,请尝试以下操作:
Thread1
Thread2
是要访问同一文件的两个线程

  • Thread1
    启动,请求锁定
    File1.docx
    并睡眠2分钟
  • Thread2
    启动,并对
    File2.docx
    进行独占锁定,现在希望访问
    File1.docx
  • Thread1
    唤醒,现在想要访问
    File2.docx
    ,该文件由
    Thread2
  • 这是一个循环等待条件


    简单?=)

    这是“行动中的死锁”的一个工作示例。基本上,您需要做的(以及在现实世界中通常发生的情况)是以相反的顺序锁定对象:一个线程中的第一个、第二个和另一个线程中的第一个、第二个:

    package stackoverflow;
    
    public class Deadlock {
    
        final static String a = new String("A");
        final static String b = new String("B");
    
        public static void main(String[] args) {
    
            final Thread abLock = new Thread() {
                @Override
                public void run() {
                    lock(a, b);
                }
            };
    
            final Thread baLock = new Thread() {
                @Override
                public void run() {
                    lock(b, a);
                }
            };
    
            abLock.start();
            baLock.start();
    
        }
    
        static void lock(String first, String second) {
            synchronized (first) {
                System.out.println(first);
                sleep();
                synchronized (second) {
                    System.out.println(second);
                }
            }
        }
    
        static void sleep() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    

    对不起,我不明白。这可能是因为我不熟悉线程。根据我的理解,我只制作了threadexample类的一个对象。Thread1和Thread2正在竞争获得sum()和sub()的锁。您的示例不正确<只要
    线程
    未释放其锁,则代码>线程2将被阻止,但这不是死锁。当两个(或多个)线程被永久阻止时,就会发生死锁情况,因为每个线程都被阻止,等待获取另一个线程拥有的独占资源。
    package stackoverflow;
    
    public class Deadlock {
    
        final static String a = new String("A");
        final static String b = new String("B");
    
        public static void main(String[] args) {
    
            final Thread abLock = new Thread() {
                @Override
                public void run() {
                    lock(a, b);
                }
            };
    
            final Thread baLock = new Thread() {
                @Override
                public void run() {
                    lock(b, a);
                }
            };
    
            abLock.start();
            baLock.start();
    
        }
    
        static void lock(String first, String second) {
            synchronized (first) {
                System.out.println(first);
                sleep();
                synchronized (second) {
                    System.out.println(second);
                }
            }
        }
    
        static void sleep() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    
    }