案例说明
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转账成功
可以分析得出在非高并发时期两个用户都能转账成功,随着并发的频率越高转账成功率会有所下滑