欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程死锁实例,线程锁并不可怕 多线程Javathread编程活动 

程序员文章站 2022-07-14 20:52:45
...
为了测试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、在生产者--消费者模型中,使用仓库的概念使得生产者与消费者脱离,即生产者不会需要去拿消费者的锁,消费者也不会去需要拿生产者的锁。他们只需要去拿仓库的锁。