Java实现死锁

来源:互联网 发布:看舌头知病情图片 编辑:程序博客网 时间:2024/06/01 12:53

在多线程中,为了保证数据等准确性和一致性,一般在进行共享数据进行操作等时候,我们都会进行加锁,保证同一时间只有一个线程在操作这个对象。由于加锁的原因,如果一不注意的话很容易导致死锁。死锁的原因是两个线程或者多个线程在互相等待对方释放资源,一直在阻塞等待,这就造成了死锁。由于Java中没有对死锁进行监管的东西,在死锁中,线程会一直被阻塞,程序不会有任何提示的消息,也无法继续下去。

下面是一个死锁的例子,可以帮助大家理解死锁的机制:

package lock;/** * Created by pozhen on 17/2/12. * 1.首先开启一个线程(副线程),启动线程后,会先进入run方法,run方法执行b.hold(a)方法,给b对象加了锁,然后休眠200ms * 2.然后主线程几乎是和副线程同时,但是会慢上一些进入init()方法,然后执行a.hold(b)方法,给a对象加了锁,然后休眠200ms * 3.b对象会提前结束休眠,将要执行代码4,需要给a对象加锁,但是现在a对象的锁被副线程持有,所以主线程阻塞,等待副线程释放a对象的锁。 * 4.这时候副线程的休眠也结束了,将要执行代码2,需要给b加锁,但是现在b对象的锁被主线程持有,所以副线程阻塞,等待主线程释放b对象的锁。 * 5.最后,主线程阻塞在等副线程释放锁,副线程也在阻塞等待主线程释放锁,这时候就一直等待下去,无穷无尽,这就造成了死锁。 */public class DeadLockExample implements Runnable{    class A {        public synchronized void hold(B b) {            try {                System.out.println(Thread.currentThread().getName()+"目前持有A的锁");//代码1                Thread.sleep(200);            }catch (Exception e) {                e.printStackTrace();            }            b.last();        }        public synchronized void last() {            System.out.println(Thread.currentThread().getName()+"的A对象企图访问B对象的last方法,准备要给B对象加锁");//代码2        }    }    class B {        public synchronized void hold(A a) {            try {                System.out.println(Thread.currentThread().getName()+"目前持有B的锁");//代码3                Thread.sleep(200);            }catch (Exception e) {                e.printStackTrace();            }            a.last();        }        public synchronized void last() {            System.out.println(Thread.currentThread().getName()+"的B对象企图访问A对象的last方法,准备要给A对象加锁");//代码4        }    }    A a = new A();    B b = new B();    public void init() {        Thread.currentThread().setName("主线程");        a.hold(b);    }    @Override    public void run() {        Thread.currentThread().setName("副线程");        b.hold(a);    }    public static void main(String[] args) {        DeadLockExample deadLockExample = new DeadLockExample();        new Thread(deadLockExample).start();        deadLockExample.init();    }}
0 0
原创粉丝点击