关于同步_死锁_why

原创 2012年03月29日 23:55:16

能否写一个容易产生死锁的程序?

 

死锁的现象:程序挂着不动了

死锁的本质:所有的钥匙都被占用了,导致双方都失去代码的执行权;

 

线程安全隐患:一个线程还没执行完必须同步的代码,cpu就把运行权交给另一个共享代码的线程了,导致错乱;

解决方案:把该同步完成的代码封装到一个{}中,再没有执行完之前,其他线程没有权利读取和执行该{}中的代码;

同步安全原理:给需要同步的代码加个锁(synchronized),给锁配一把钥匙(Object / this / .class ),谁在执行该代码,谁就得到对应的钥匙;

                           因为只有一把钥匙,所以其他线程没有钥匙,就打不开锁,就得不到锁中的代码,也就是没权利执行锁中的代码,这样就安全了;

 

有可能产生的问题:

                   当A线程执行到一半,失去cpu的执行权,B线程得到cpu执行权,B把锁中的代码执行到一半发现里边有一部分代码加了锁,可是钥匙在A线程代码的锁上,这时,B线程可住了,需要得到A线程执行完剩下的代码后才能拿到钥匙,杯具的事情来了,因为这时B线程锁上的钥匙刚好就是A线程剩下的代码的锁的钥匙,各持一把钥匙,而且钥匙都拿不出来,因为双方锁中的代码都没执行完;(这时就是死锁)

 

写一个死锁的代码:

思路:让两条线程,各持对方需要的钥匙;

                        1,A线程和B线程的run方法中的代码加上嵌套锁;

                        2,两条线程的嵌套锁共用两把钥匙;

                        3,B线程的外套锁共用A线程内套锁的钥匙,内套锁共用A线程的外套锁的钥匙;

 

代码体现:

public class DeadLockTest {

 /**
  * 面试:写一个死锁事例
  * 两锁嵌套
  *
  * 同步安全的原理:
  * 当A线程在执行一半的代码后失去执行权,那么共享这些代码的其他线程,没有权利执行这些代码;
  * 只有当我把同步中的所有代码执行完,其他线程才能进来执行;
  *
  * 一锁不能二用,对象不可二用;
  *
  */
 public static class DeadLock implements Runnable {
  //成员变量 
  private boolean flag;
  //构造函数
  DeadLock(boolean flag){
   this.flag = flag;
  }
  //成员函数
  public void run(){
   //if else 制造双体
   if(flag){
    while(true){
     synchronized(MyLock.keyb){
      System.out.println("Thread 1 拿着 keyb");
      synchronized(MyLock.keya){
       System.out.println("Thread 1 拿着 keya");
       System.out.println("Thread 1 释放 keya");
      }
      System.out.println("Thread 1 释放 keyb");
     }
    }
   }
   else{
    while(true){
     synchronized(MyLock.keya){
      System.out.println("Thread 2 拿着 keya");
      synchronized(MyLock.keyb){
       System.out.println("Thread 2 拿着 keyb");
       System.out.println("Thread 2 释放 keyb");
      }
      System.out.println("Thread 2 释放 keya");
     }
    }//复制死锁时,最后一部分打印结果:
      /*
     Thread 2 拿着 keya
     Thread 2 拿着 keyb
     Thread 2 释放 keyb
     Thread 2 释放 keya
     Thread 2 拿着 keya    // 2拿a不放
     Thread 1 拿着 keyb */ // 1拿b不放   两把钥匙被两个人拿到时,就死了
   } 
  }
 }
 //准备两个锁的钥匙
 public static class MyLock{
  static Object keya = new Object();
  static Object keyb = new Object();
 }

 public static void main(String[] args) {
  // 建立事物对象
  DeadLock d1 = new DeadLock(true);
  DeadLock d2 = new DeadLock(false);
  // 建立线程,把对象导入线程
  Thread t1 = new Thread(d1);
  Thread t2 = new Thread(d2);
  // 启动线程
  t1.start();
  t2.start();
  

 }

}

 

                   

相关文章推荐

死锁_why

能否写一个容易产生死锁的程序?   死锁的现象:程序挂着不动了 死锁的本质:所有的钥匙都被占用了,导致双方都失去代码的执行权;   线程安全隐患:一个线程还没执行完必须同步的代码,cpu就把...

Java线程的同步与死锁

  • 2014年09月14日 14:56
  • 168KB
  • 下载

操作系统同步与死锁

  • 2015年02月01日 00:00
  • 127KB
  • 下载

java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)

多线程系列教程: java多线程-概念&创建启动&中断&守护线程&优先级&线程状态(一) java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(二) 本篇我...

JAVA_线程同步与死锁

  • 2012年08月16日 11:45
  • 32KB
  • 下载

操作系统同步通信和死锁

  • 2011年11月24日 11:19
  • 650KB
  • 下载

进程同步互斥——不死锁的哲学家问题

一、需求分析 (1)一张圆桌上有一大碗面,5个盘子,每位哲学家一个,还有五把叉子。每位想吃饭的哲学家将坐到桌子旁分配给他的位置上,使用盘子两侧的叉子,取面和吃面。问题是:设计一套礼仪(算法)以允许哲...

操作系统 同步通信与死锁

  • 2011年02月16日 17:08
  • 872KB
  • 下载

Java中的同步与死锁

1、Java中使用同步的必要性 设计一个买票程序,安排三个票贩子同时售票,为了更清楚的模拟买票过程,在买票操作中加入500毫秒的延时,售票代码和执行结果如下: package org.mole.x...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于同步_死锁_why
举报原因:
原因补充:

(最多只允许输入30个字)