A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 史政法 中级黑马   /  2013-2-20 13:19  /  1855 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 史政法 于 2013-2-21 19:45 编辑
  1. class Test implements Runnable
  2. {
  3.         private boolean flag;
  4.         Test(boolean flag)
  5.         {
  6.                 this.flag = flag;
  7.         }
  8.         public void run()
  9.         {
  10.                 if (flag)
  11.                 {
  12.                         while(true)
  13.                         {
  14.                                 synchronized(MyLock.locka)
  15.                                 {
  16.                                         System.out.println(Thread.currentThread().getName()+" : a");
  17.                                         synchronized(MyLock.lockb)
  18.                                         {
  19.                                                 System.out.println(Thread.currentThread().getName()+" : b");
  20.                                         }
  21.                                 }
  22.                         }
  23.                 }
  24.                 else
  25.                 {
  26.                         while(true)
  27.                         {
  28.                                 synchronized(MyLock.lockb)
  29.                                 {
  30.                                         System.out.println(Thread.currentThread().getName()+" : b");
  31.                                         synchronized(MyLock.locka)
  32.                                         {
  33.                                                 System.out.println(Thread.currentThread().getName()+" : a");
  34.                                         }
  35.                                 }
  36.                         }
  37.                 }
  38.         
  39.         }
  40. }

  41. class MyLock
  42. {
  43.         static Object locka = new Object();
  44.         static Object lockb = new Object();
  45. }

  46. class DeadLockTest
  47. {
  48.         public static void main(String[] args)
  49.         {
  50.                 Thread t1 = new Thread(new Test(true));//创建一个线程,传入一个对象参数,
  51.                 Thread t2 = new Thread(new Test(false));//创建一个线程,传入另一个对象参数
  52.                 t1.start();
  53.                 t2.start();
  54.         }
  55. }
复制代码
两个线程操作的不是两个不一样的对象么?为什么也能死锁,就像是操作同一个对象一样?什么情况?求程序运行时内存中过程。

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

12 个回复

倒序浏览
两个线程运行的是同一个run方法,第一个线程开启拿到locka锁,还没有执行到synchronized(MyLock.lockb)的时候,第二个线程开启,拿到lockb锁,然后第一个线程
又抢回cpu执行权,但是需要lockb锁,而lockb锁在第二个线程里,第二个线程同时也在等着要locka锁,所以就死锁了。

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

回复 使用道具 举报
俩个线程操作同一个共享参数是用同步,你这个情况是因为2个线程在运行时都拥有一把锁,然后在运行的时候想要对方的锁,这个时候就发生了死锁

评分

参与人数 1黑马币 +9 收起 理由
李培根 + 9 赞一个!

查看全部评分

回复 使用道具 举报
zuiaikou 发表于 2013-2-20 13:33
两个线程运行的是同一个run方法,第一个线程开启拿到locka锁,还没有执行到synchronized(MyLock.lockb)的时 ...

,,,,,,为什么传入两个不同的对象,却运行的是同一个run方法???给点理论知识啊,你这就是在告诉我死锁是怎么产生的,没用,不靠谱啊
回复 使用道具 举报
李挺 发表于 2013-2-20 13:36
俩个线程操作同一个共享参数是用同步,你这个情况是因为2个线程在运行时都拥有一把锁,然后在运行的时候想 ...

这俩线程中没用到共享的参数啊,,,,new了俩对象出来的啊,,,,
回复 使用道具 举报
你传入的两个对象,在方法区中,都有各自的run方法代码,但是代码的内容是一致的,不是运行的一个run方法,是运行了两个相同过程和内容的run方法

操作同一个共享数据的多个方法在需要同步的情况下要使用同一把锁,这样才能达到同步的效果,不论这个方法是不是在同一个类中

死锁是发生在两把锁嵌套的情形下,锁必须是交替内外的顺序,比如方法1上加了A锁,而在方法内部加了B锁,方法2上加了B锁,而内部加了A锁,当有多个线程同时来执行这两个方法时,便会产生死锁的情况。原理视频里讲的也很清楚了
回复 使用道具 举报
你这快堪称死锁经典案例了,是不是为了死锁写的代码?
线程1:
synchronized(MyLock.locka)
{
             System.out.println(Thread.currentThread().getName()+" : a");
             synchronized(MyLock.lockb)线程执行到这里时拿着MyLock.locka这个锁,并想要拿到MyLock.lockb这个锁,但是MyLock.lockb这时线程2占用着
{
             System.out.println(Thread.currentThread().getName()+" : b");
            }
}
线程2:
synchronized(MyLock.lockb)
{
         System.out.println(Thread.currentThread().getName()+" : b");
         synchronized(MyLock.locka)线程执行到这里时拿着MyLock.lockb这个锁,并想要拿到MyLock.locka这个锁,但是MyLock.locka这时线程1占用着
{

         System.out.println(Thread.currentThread().getName()+" : a");
         }
}
两个static属性各只有一份,就是两个锁,两个线程各拿一个,并都想得到对方手里的那个锁
回复 使用道具 举报
柴乔军 发表于 2013-2-20 13:52
你传入的两个对象,在方法区中,都有各自的run方法代码,但是代码的内容是一致的,不是运行的一个run方法, ...

这个哥们靠谱,,,,,,要的就是这句话:
操作同一个共享数据的多个方法在需要同步的情况下要使用同一把锁,这样才能达到同步的效果,不论这个方法是不是在同一个类中,,,,

一个类中有个共享数据,可以创建N多类,N多类中也有N多的方法存放在方法区,但是只要加上同一把锁以后,线程在运行的时候就只能同步运行,不管是不是同一个类,但是运算不同类中不同的run方法的时候就需要去拿锁了,理解的对吗?另外你是在哪知道这些的呢,哥们?视频上没讲到过啊,提都没提过。
回复 使用道具 举报
夏振博 发表于 2013-2-20 13:54
你这快堪称死锁经典案例了,是不是为了死锁写的代码?
线程1:
synchronized(MyLock.locka)

你们,你们,你们,你们这些回答问题的,真的知道我在问什么么????
蛋疼,,,,,,
回复 使用道具 举报
{:soso_e113:}理解的对的,仔细看视频,看个2,3遍的就理解到了,你已经能想到这了,再看一次视频,自己写一个死锁程序,写不同的类,不同的run方法,一测试你就明白啦
回复 使用道具 举报
这是两个线程互锁的问题


  1. class Test implements Runnable {
  2.         private boolean flag;

  3.         Test(boolean flag) {
  4.                 this.flag = flag;
  5.         }

  6.         public void run() {
  7.                 if (flag) {
  8.                         while (true) {
  9.                                 //线程t1给locka上锁
  10.                                 synchronized (MyLock.locka) {
  11.                                         //打印a
  12.                                         System.out.println(Thread.currentThread().getName()
  13.                                                         + " : a");
  14.                                         //线程t1再给lockb上锁
  15.                                         synchronized (MyLock.lockb) {
  16.                                                 //打印b
  17.                                                 System.out.println(Thread.currentThread().getName()
  18.                                                                 + " : b");
  19.                                         }
  20.                                 }
  21.                         }
  22.                 } else {
  23.                         while (true) {
  24.                                 //线程t2拿lockb,但是,lockb有可能正被线程t1用着呢,拿不到,程序就有可能卡在这儿
  25.                                 synchronized (MyLock.lockb) {
  26.                                         System.out.println(Thread.currentThread().getName()
  27.                                                         + " : b");
  28.                                         synchronized (MyLock.locka) {
  29.                                                 System.out.println(Thread.currentThread().getName()
  30.                                                                 + " : a");
  31.                                         }
  32.                                 }
  33.                         }
  34.                 }

  35.         }
  36. }

  37. class MyLock {
  38.         static Object locka = new Object();
  39.         static Object lockb = new Object();
  40. }

  41. public class DeadLockTest {
  42.         public static void main(String[] args) {
  43.                 Thread t1 = new Thread(new Test(true));// 创建一个线程,传入一个对象参数,
  44.                 Thread t2 = new Thread(new Test(false));// 创建一个线程,传入另一个对象参数
  45.                 t1.start();
  46.                 t2.start();
  47.         }
  48. }
复制代码
回复 使用道具 举报
不管是new 了几个线程,但是运行这个run方法需要的锁是唯一的,就是谁持有锁谁可以运行,当一个线程运行这段代码时,其他的线程都没有锁,所以只有等待它把锁交出来。
就像毕老师举得火车上厕所的例子,n个人都有上厕所的权利,但是只有有锁的才可以进入厕所,没锁的等到有锁的人把锁交出来才能上。
回复 使用道具 举报
  1. class Single
  2. {
  3.         private static final Single s = new Single();
  4.         private Single(){}
  5.         public static Single getInstance()
  6.         {
  7.                 return s;
  8.         }
  9.         private int x = 200;
  10.         public void setNum(int x)
  11.         {
  12.                 this.x = x;
  13.         }
  14.         public int getNum()
  15.         {
  16.                 return x;
  17.         }

  18. }

  19. class Demo implements Runnable
  20. {
  21.         Single s = Single.getInstance();
  22. //        s.setNum(300);
  23.         int x = s.getNum();
  24.         boolean flag;
  25.         Demo(boolean flag)
  26.         {
  27.                 this.flag = flag;
  28.         }
  29.         public void run()
  30.         {
  31.                 if (flag)
  32.                 {
  33.                         while(x>0)
  34.                         {
  35.                                 synchronized(Locket.a)
  36.                                 {
  37.                                         System.out.println("if Locket.a  "+x--);
  38.                                         synchronized(Locket.b)
  39.                                         {
  40.                                                 System.out.println("if Locket.b  "+x--);

  41.                                         }
  42.                                 }
  43.                         }
  44.                        
  45.                 }
  46.                 /*
  47.                 else
  48.                 {
  49.                         synchronized(Locket.b)
  50.                         {
  51.                                 System.out.println("else Locket.b");
  52.                                 synchronized(Locket.a)
  53.                                 {
  54.                                         System.out.println("else Locket.a");
  55.                                 }
  56.                         }
  57.                 }
  58.                 */
  59.         }
  60. }

  61. class Demo2 implements Runnable
  62. {
  63.         Single s = Single.getInstance();
  64.         int x = s.getNum();
  65.         boolean flag;
  66.         Demo2(boolean flag)
  67.         {
  68.                 this.flag = flag;
  69.         }
  70.         public void run()
  71.         {
  72.                 if (flag == false)
  73.                 {
  74.                         while(x>0)
  75.                         {
  76.                                 synchronized(Locket.a)//这个地方要换成.b就是挂,就会出现死锁的情况,
  77.                                 {
  78.                                         System.out.println("else Locket.B  "+x--);
  79.                                         synchronized(Locket.b)
  80.                                         {
  81.                                                 System.out.println("else Locket.A  "+x--);

  82.                                         }
  83.                                 }
  84.                         }
  85.                 }
  86.                 /*
  87.                 else
  88.                 {
  89.                         synchronized(Locket.b)
  90.                         {
  91.                                 System.out.println("else Locket.A");
  92.                                 synchronized(Locket.a)
  93.                                 {
  94.                                         System.out.println("else Locket.B");
  95.                                 }
  96.                         }
  97.                 }
  98.                 */
  99.         }
  100. }
  101. class Locket
  102. {
  103.         static Object a = new Object();
  104.         static Object b = new Object();
  105. }
  106. class DeadLockTest
  107. {
  108.         public static void main(String[] args)
  109.         {
  110.                 new Thread(new Demo(true)).start();
  111.                 new Thread(new Demo2(false)).start();
  112.         }
  113. }
复制代码
共享同一个数据搞不出来,搞了个两个对象,两个数据,但是用多线程操作同一把锁的代码,方便后来人。。。。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马