美文网首页
Java死锁

Java死锁

作者: Kris_Ni | 来源:发表于2019-06-16 22:56 被阅读0次

    死锁的四个必要条件
    1)互斥条件,即某个资源在一段时间内只能由一个线程占有,不能同时被两个或两个以上的线程占有
    2)不可抢占条件,线程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者线程自行释放
    3)占有且申请条件,线程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外线程占有,此时该线程阻塞;但是,它在等待新资源之时,仍继续占用已占有的资源。
    4)循环等待条件,存在一个线程等待序列{P1,P2,...,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,......,而Pn等待P1所占有的的某一资源,形成一个线程循环等待环
    解决死锁的办法:加锁顺序,死锁检测

    下面通过代码实例来讲解一下如何去写一个死锁代码&如何去解决死锁问题

    public class DeadLockTest {
        static class MyTask implements Runnable {
            Object obj1 = "obj1";
            Object obj2 = "obj2";
            int flag;
            private void setFlag(int flag) {
                this.flag = flag;
            }
            @Override
            public void run() {
                if (flag == 1) {
                    synchronized (obj1) {
                        System.out.println("locking "+obj1);    //占用obj1
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (obj2) {
                            System.out.println("使用顺序 obj1 -> obj2");
                        }
                    }
                } else if (flag == 2) {
                    synchronized (obj2) {
                        System.out.println("locking "+obj2);    //占用obj2
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        synchronized (obj1) {
                            System.out.println("使用顺序 obj2 -> obj1");
                        }
                    }
                }
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
    
            MyTask myTask = new MyTask();
    
            myTask.setFlag(1);
            Thread thread1 = new Thread(myTask);
            thread1.start();
    
            //保证线程thread1优先执行
            Thread.sleep(100);
    
            myTask.setFlag(2);
            Thread thread2 = new Thread(myTask);
            thread2.start();
        }
    }
    
    

    通过两个线程去竞争资源从而达到死锁目的
    解决方案

            MyTask myTask1 = new MyTask();
            myTask1.setFlag(2);
            Thread thread2 = new Thread(myTask1);
            thread2.start();
    

    理论上是可以解决死锁,但是并没有成功,WTF!想了好久原来是字符串常量的问题,需要通过new String()方式解决,即

            Object obj1 = new String("obj1");
            Object obj2 = new String("obj2");
    

    相关文章

      网友评论

          本文标题:Java死锁

          本文链接:https://www.haomeiwen.com/subject/gupnfctx.html