java多线程死锁实例,线程锁并不可怕

为了测试java多线程死锁

得到java多线程死锁的直观感觉,写出以下测试代码。

public class TestDeadLock
{
public static void main(String[] args)
{
A a=new A();
B b=new B(a);
a.set(b);
Thread t1=new Thread(a);
Thread t2=new Thread(b);
t1.start();
t2.start();
}
}

class A implements Runnable
{
public B b;
public void run()
{
while (true)
{
synchronized(this)
{
b.write();
}
}
}
public void write()
{
synchronized (this)
{
System.out.println("a write");
}
}
public void set(B b)
{
this.b=b;
}
}
class B implements Runnable
{
public A a;
public B(A a)
{
this.a=a;
}
public void write()
{
synchronized (this)
{
System.out.println("b write");
}
}
public void run()
{
while (true)
{
synchronized(this)
{

a.write();
}
}
}
}

1、代码导读

对象a使用独立线程去调用对象b的方法。

对象b使用独立线程去调用对象a的方法。

对象a在调用b的方法之前对自己加锁,调用对象b后对对象b加锁。

对象b在调用a的方法之前对自己加锁,调用对象a后对对象a加锁。

2、死锁形成原因解读

a首先锁了自己,b锁了自己,

a去拿b的锁,发现b已经锁定了,则等待b的锁释放

b去拿a的锁,发现a已经锁定,则等待a释放。

就这样a等b,b也等a,造成了死锁的问题。

3、死锁的必要条件

两个或两个以上的线程在活动

某个线程拿到了一个锁以后,还想去拿第二个锁,即锁的嵌套

4、预防死锁的编程规范和方法。

@1、如果某个对象拿到了自己的锁,如果想要去拿另外对象的锁,一定要先释放自己的锁。任何锁嵌套都是不安全的

@2、加锁的代码块,其中尽量不要去调用另外的方法。因为很难在子方法中施放锁。如果需要调用到其他的方法,需确定该方法以及其子分支肯定不会申请本锁以外的锁。

@3、遇到锁中必须调用其他锁的情况,必须确定下个锁对象中不会再回调。所有锁调用都是拓扑序的。

@4、在生产者--消费者模型中,使用仓库的概念使得生产者与消费者脱离,即生产者不会需要去拿消费者的锁,消费者也不会去需要拿生产者的锁。他们只需要去拿仓库的锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值