JAVA 使用Lock解决死锁问题

案例说明

a用户向b转账,a用户需要持有自己的a锁,并且获取b锁才能完成转账操作

b用户向a转账,b用户需要持有自己的b锁,并且获取a锁才能完成转账操作

使用synchronized将会出现死锁

package com.yujie;

public class DeadlockDemoTest {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        Thread aThread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a){
                    sleep(1);
                    synchronized (b){
                        System.out.println("a向b转账成功");
                    }
                }
            }
        },"A");

        Thread bThread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (b){
                    sleep(2);
                    synchronized (a){
                        System.out.println("b向a转账成功");
                    }
                }
            }
        },"B");

        aThread.start();
        bThread.start();

    }

    public static void sleep(int seconds){
        try {
            Thread.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

采用Lock锁解决死锁问题

package com.yujie;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SolveDeadlockDemoTest {
    public static void main(String[] args) {
        Lock aLock= new ReentrantLock();
        Lock bLock= new ReentrantLock();

        Thread aThread = new Thread(new Runnable() {
            @Override
            public void run() {
              aLock.lock();
                boolean state=false;
                try {
                    sleep(1);
                    state = bLock.tryLock();
                    if(state){
                        System.out.println(Thread.currentThread().getName()+":a给b转账成功");
                    }else{
                        System.out.println(Thread.currentThread().getName()+":释放a的锁,让b用户执行");
                    }

                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    aLock.unlock();
                    //释放拿到的b锁
                    if(state){
                        bLock.unlock();
                    }
                }

            }
        },"A");

        Thread bThread = new Thread(new Runnable() {
            @Override
            public void run() {
                bLock.lock();
                boolean state=false;
                try {
                    sleep(2);
                    state = aLock.tryLock();
                    if(state){
                        System.out.println(Thread.currentThread().getName()+":b给a转账成功");
                    }else{
                        System.out.println(Thread.currentThread().getName()+":释放b的锁,让a用户执行");
                    }

                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    bLock.unlock();
                    //释放拿到的a锁
                    if(state){
                        aLock.unlock();
                    }
                }
            }
        },"B");

        aThread.start();
        bThread.start();

    }

    public static void sleep(int seconds){
        try {
            Thread.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

使用lock锁的运行效果有三种

1.高并发两个线程之间时间差10ms

B:释放b的锁,让a用户执行
A:释放a的锁,让b用户执行

2.高并发两个线程之间时间差50ms

A:释放a的锁,让b用户执行
B:b给a转账成功

3.短暂并发两个线程之间时间差200ms

A:a给b转账成功
B:b给a转账成功

可以分析得出在非高并发时期两个用户都能转账成功,随着并发的频率越高转账成功率会有所下滑

猜你喜欢

转载自blog.csdn.net/qq_42058998/article/details/129253300