java线程理解之死锁问题

/*
 时间:2015年3月13日10:35:44
 测试synchronized关键字的使用,以及死锁的理解
 在java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任意时刻,智能有一个线程访问该对象。
 关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时,表明该对象在任意时刻只能有一个线程访问。
 
 
 同一类线程共享代码和数据空间指的是共享线程体,和静态成员变量或者成员方法。这通过该程序可以得到验证。(因为倘若注销掉两个Object类型前的static或者任意注销其中一个)
 程序都可以正常运行,而不会发生死锁。
 
 TestDeadLock 实现了Runnable接口
 Runnable 接口应该由那些打算 通过某一线程 执行其实例的类来实现。类必须定义一个称为 run 的无参数方法。
 设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议
 Runnable 为非 Thread 子类的类提供了一种激活方式。通过实例化某个 Thread 实例 并将自身作为运行目标,
 就可以运行 实现 Runnable  的类而无需创建 Thread 的子类。
 大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。
 这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。
 
 使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。



 程序理解:类TestDeadLock实现了Runnable接口。
 并且在类中定义了成员变量flag, object类型 obj1 , obj2,当然两个类型都是静态的,也就是线程所共享的数据
 
 定义了自己的run线程体
 看main方法:
  首先定义了两个可以Runnable的对象test1和test2。
  并把各自的成员变量flag标记设置为1和0
  分别使用test1和test2分配了两个新的线程对象t1和t2
  启动两个线程。
 根据程序运行的结果来看,(因为线程不可控制,每一次运行会得到不同的结果)在程序运行的结果中,我把两种运行的结果都列了出来,我们分析第一种
 flag = 1
 flag = 0
 flag = 0
 
 首先跑起来的线程是t1,这我们可以通过输出的第一条语句flag=1看出,判断,锁定obj1对象,保证在任意时刻只有一个线程访问该对象obj1,也就是t1线程。休眠500毫秒
 输出第二句flag = 0表示t2线程运行,判断,锁定obj2对象,在obj2对象添加了互斥锁。休眠500毫秒。
 t1线程运行,要锁定obj2对象,发现该对象已经被t2线程锁定,无法完成资源获取,只能等待。
 然后t2线程运行
 
 
 ?      ?
 
 ,这个线程运行也是从run方法一进去开始吗?这样的话,第三条输出语句就可以解释了。
 
 
 
 
 要锁定obj1对象,发现该对象已经被t1线程锁定,只能等待。等待获取已经被t1线程锁定的obj1.
 这样造成了死锁。
 
 
  而为了理解第三次运行的结果。(加入了分号后//等语句)
  首相建立了两个Runnable的对象test1,test2,并且设置相应的flag
  分别建立了两个线程。t1 t2. 然后启动这两个线程
  从结果看,首先运行了t1线程输出第一条语句,判断,锁定obj1,休眠500毫秒
  第二个线程运行,输出第二条语句flag = 0 判断 输出第三条语句 锁定obj2 休眠500毫秒
  然后t1线程重新运行,接着上次运行的地址。因为没有发生异常,执行的是catch下一句,输出了flag = 1 将要锁定obj2
  无奈obj2已经被线程t2锁定了,等待线程t2释放这个对象资源。
  t1接着上次运行到的位置,同理也是catch块的下一个语句输出的语句为flag = 0 将要锁定obj1
  无奈obj1对象资源被线程t1锁定了,等待线程t1释放这个对象资源
  因此产生了死锁。

 


*/

public class TestDeadLock implements Runnable {
 public int flag = 1;
 public static Object obj1 = new Object();
 public static Object obj2 = new Object();
 
 public static void main(String[] args) {
  TestDeadLock test1 = new TestDeadLock();
  TestDeadLock test2 = new TestDeadLock();
  test1.flag = 1;
  test2.flag = 0;
  Thread t1 = new Thread(test1);
  Thread t2 = new Thread(test2);
  
  t1.start();
  t2.start();
  
  
 }
 
 public void run() {
  System.out.println("flag = " + flag);
  if (flag == 1) {
   synchronized(obj1) {
    try {
     Thread.sleep(500);
     
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println("flag = " + flag + " 将要锁定obj2");//
    synchronized(obj2) {
     System.out.println("1");
    }
    
   }
   System.out.println("flag = " + flag + " 执行完毕");//
   
  } else if (flag == 0) {
   System.out.println("flag = " + flag);
   synchronized(obj2) {
    try {
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println("flag = " + flag + " 将要锁定obj1");//
    synchronized(obj1) {
     System.out.println("0");
    }
   }
   System.out.println("flag = " + flag + " 执行完毕");//
  }
  
 
  System.out.println("flag = " + flag + "run() 执行完毕");//
 }
}
/*
=====================

D:\java\thread>javac TestDeadLock.java

D:\java\thread>java TestDeadLock
flag = 1
flag = 0
flag = 0

---------------------------


D:\java\thread>javac TestDeadLock.java

D:\java\thread>java TestDeadLock
flag = 0
flag = 1
flag = 0

-------------------------------------

D:\java\thread>javac TestDeadLock.java

D:\java\thread>java TestDeadLock
flag = 0
flag = 1
flag = 0
flag = 1 将要锁定obj2
flag = 0 将要锁定obj1




=====================

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值