在多线程的情况下,我们也可能会使用线程同步机制,例如两个人对同一个银行账号进行取款存款操作,如果同时存取款,当网络异常时,一个人在取完钱之后,后端数据库并没有更细数据,那么另一个人马上取钱就有可能造成金钱损失,所以我们这里需要使用线程同步机制,实现在一个人取完钱之后,在数据更新之前,另一个人不能进行取款操作。这就需要使用到synchronized,但是我们在使用synchronized的时候也要需要避免死锁的发生,下面就是一个死锁的经典例子。 package DeadLock; public class DeadLock { public static void main(String[] args) { //创建两个Object对象 Object o1 = new Object(); Object o2 = new Object(); //创建两个线程对象,并且共享o1和o2对象 Thread t1 = new Thread(new MyThread1(o1, o2)); Thread t2 = new Thread(new MyThread2(o1, o2)); //给两个线程重命名 t1.setName("t1"); t2.setName("t2"); //启动两个线程 t1.start(); t2.start(); } } class MyThread1 implements Runnable { Object o1; Object o2; public MyThread1() { } public MyThread1(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } @Override public void run() { //先抢占o1的锁 synchronized (o1) { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } //紧跟着再锁o2 synchronized (o2) { } } } } class MyThread2 implements Runnable { Object o1; Object o2; public MyThread2() { } public MyThread2(Object o1, Object o2) { this.o1 = o1; this.o2 = o2; } @Override public void run() { //先抢占o2的锁 synchronized (o2) { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } //紧跟着再锁o1 synchronized (o1) { } } } } 由于MyThread1先抢占了o1的锁,MyThread2先抢占了02的锁,此时MyThread1没抢占到o2的锁,所以并没有释放o1的锁,一直处于就绪等待状态,而MyThread2抢不到o1的锁,所以MyThread2就一直处于就绪等待状态,并且不释放o2的锁,造成死锁。此时程序一直不会结束,也不会报错,所以死锁是最难发现的一种程序bug,我们只有自己能手动写死锁,才会知道怎么避免死锁的出现。
java手动实现synchronized死锁
最新推荐文章于 2024-05-10 09:14:14 发布