`
ak_2005
  • 浏览: 793 次
  • 性别: Icon_minigender_1
  • 来自: 成都
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

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、在生产者--消费者模型中,使用仓库的概念使得生产者与消费者脱离,即生产者不会需要去拿消费者的锁,消费者也不会去需要拿生产者的锁。他们只需要去拿仓库的锁。
分享到:
评论

相关推荐

    java范例开发大全

    实例232 多线程同步方法的实例 436 实例233 ATM存取一体机(线程同步互斥) 437 实例234 我的钱哪里去了 440 实例235 门锁打不开了(死锁) 444 实例236 门锁终于被打开了(解决死锁) 446 实例237 一个死锁的例子 ...

    java范例开发大全源代码

     实例1 开发第一个Java程序 7  第2章 Java基础类型与运算符(教学视频:39分钟) 9  2.1 基础类型 9  实例2 自动提升 9  实例3 自动转换 10  实例4 常用基础类型之强制转换 11  2.2 运算符 12 ...

    Java范例开发大全 (源程序)

    第1篇 Java编程基础  第1章 Java开发环境的搭建(教学视频:9分钟) 2  1.1 理解Java 2  1.2 搭建Java所需环境 3  1.2.1 下载JDK 3  1.2.2 安装JDK 4 ... 实例224 资源搜索并下载(线程...

    Java范例开发大全(全书源程序)

    实例232 多线程同步方法的实例 436 实例233 ATM存取一体机(线程同步互斥) 437 实例234 我的钱哪里去了 440 实例235 门锁打不开了(死锁) 444 实例236 门锁终于被打开了(解决死锁) 446 实例237 一个死锁的...

    Java JDK实例宝典

    全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...

    java范例开发大全(pdf&源码)

    实例232 多线程同步方法的实例 436 实例233 ATM存取一体机(线程同步互斥) 437 实例234 我的钱哪里去了 440 实例235 门锁打不开了(死锁) 444 实例236 门锁终于被打开了(解决死锁) 446 实例237 一个死锁的例子 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例139 简单的线程死锁 180 实例140 解决线程的死锁问题 182 6.3 线程的进阶 183 实例141 使用阻塞队列实现线程同步 183 实例142 新建有返回值的线程 184 实例143 使用线程池优化多线程编程 186 实例144 Object类中...

    Java并发编程(学习笔记).xmind

    (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 (2)建模简单:通过使用线程可以讲复杂并且异步的工作流进一步分解成一组简单并且同步的工作流,每个工作流在一个单独的线程...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    Java并发编程实战

    本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则...

    疯狂JAVA讲义

    8.2.3 并不存在泛型类 298 8.3 类型通配符 298 8.3.1 使用类型通配符 300 8.3.2 设定类型通配符的上限 300 8.3.3 设定类型形参的上限 302 8.4 泛型方法 303 8.4.1 定义泛型方法 303 8.4.2 泛型方法和类型...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    JAVA核心知识点整理(有效)

    25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................

    oracle数据库经典题目

    在Oracle数据库中,数据库的操作模式分为专用服务器(DELICATED SERVER)模式和多线程服务器(MULTITHREADED SERVER)模式两种。其中,在专用服务器模式中为每个用户进程创建一个服务器进程,用户进程与服务器进程之间...

    asp.net知识库

    在SQL Server 2005中解决死锁 在 SQL Server 2005 中查询表结构及索引 sql server 2005中的DDL触发器 在 SQL Server 2005 中使用表值函数来实现空间数据库 SQL Server 2005的30个最重要特点 同时安装sql2000和sql...

Global site tag (gtag.js) - Google Analytics