您的位置:首页 > 编程语言 > Java开发

java线程死锁例子及解决方法

2017-12-03 11:20 369 查看
Java线程死锁是由于有些资源彼此交叉取用,就有可能造成死结.  

[java] view
plain copy

如1线程中 取得A对象的锁定后又要取得B对象的锁定.但是同时2线程中取得B对象的锁定后又要取得A对象的锁定.这两个线程同时发生时就会造成,1线程拿到A对象锁定后等待B对象的锁定.2线程拿到B对象锁定后等待A对象锁定.这样就会进入没有停止的等待中.  

[java] view
plain copy

线程死锁的一个简单例子:  

[java] view
plain copy

package deadLockThread;  

  

  

public class Test {  

  

private int size=0;  

  

    public synchronized void doSome(){  

size++;  

    }  

      

public synchronized void doTest(Test test){  

try {  

Thread.sleep(1000);//睡眠1秒  效果更明显  

} catch (InterruptedException e) {  

e.printStackTrace();  

}  

        test.doSome();   //另外一个对象调用synchronized 函数  需要取得该对象的对象锁定  

  

  

  

}  

  

  

  

}  

[java] view
plain copy

package deadLockThread;  

  

public class DeadLock {  

    public static void main(String[] args) {  

  

        final Test t1=new Test();  

        final Test t2=new Test();  

          

        Thread th1=new Thread(new Runnable() {  

              

            @Override  

            public void run() {  

                // TODO Auto-generated method stub  

                t1.doTest(t2);  

            }  

        });  

          

        Thread th2=new Thread(new Runnable() {  

              

            @Override  

            public void run() {  

                // TODO Auto-generated method stub  

                t2.doTest(t1);  

            }  

        });  

          

        th1.start();  

        th2.start();  

          

          

    }  

      

  

}  

[java] view
plain copy

如果真的没办法避免资源的交叉取用   我的解决方法是使用并行API在取得第一个对象锁定前先检测另外一个对象的对象锁定有没有被其他的线程拿走了.  

[java] view
plain copy

synchronized 要求线程必须取得对象锁定,才可以执行所标识的区块范围.然而使用synchronized 有许多的限制,未取得锁定的线程会直接被打断.所以我这里使用并行API Lock 替代直接操作synchronized .  

[java] view
plain copy

package deadLockThread;  

  

import java.util.concurrent.locks.Lock;  

import java.util.concurrent.locks.ReentrantLock;  

  

public class Test {  

  

    private int size = 0;  

  

    private Lock lock = new ReentrantLock();  

  

    public void doSome() {  

        System.out.println(Thread.currentThread().getName() + "获取size");  

        size++;  

    }  

  

    public void doTest(Test test) {  

  

        while (true) {  

  

            boolean myLock = this.lock.tryLock();// 尝试取得当前对象的Lock锁定  

            boolean testLock = test.lock.tryLock();// 尝试取得被传入得对象的Lock锁定  

  

            try {  

  

                if (myLock && testLock) {   //当两个对象的Lock 都获取到后再进行 操作  

                    test.doSome();  

                    break;  

                }  

  

            } finally {  

                if (myLock) {  

                    this.lock.unlock();  

                }  

                if (testLock) {  

                    test.lock.unlock();  

                }  

  

            }  

        }  

    }  

  

}  



[java] view
plain copy

package deadLockThread;  

  

public class DeadLock {  

    public static void main(String[] args) {  

  

        final Test t1 = new Test();  

        final Test t2 = new Test();  

  

        Thread th1 = new Thread(new Runnable() {  

  

            @Override  

            public void run() {  

                // TODO Auto-generated method stub  

                t1.doTest(t2);  

            }  

        });  

  

        Thread th2 = new Thread(new Runnable() {  

  

            @Override  

            public void run() {  

                // TODO Auto-generated method stub  

                t2.doTest(t1);  

            }  

        });  

  

        th1.start();  

        th2.start();  

  

    }  

  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: