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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

class DeathLockDemo1
{
        public static void main(String[] args)
        {
                Test test1=new Test(true);
                Test test2=new Test(false);
                 
                 Thread th1=new Thread(test1);
                 Thread th2=new Thread(test2);
                 th1.start();
                 th2.start();


        }
}
class MyLock
{
        public static final Object A=new Object();
        public static final Object B=new Object();
}


class Test implements Runnable
{
        private boolean flag =false;
       
    private        static int num=0;
        public Test(Boolean b)
         {
                this.flag=b;
        }

        public void run()
        {
               
                if(this.flag)
                {
                        while(true)
                        {       
                                synchronized(MyLock.A)
                                {
                                       
                                        System.out.println("A    true"+(++num)+"***********");

                                        synchronized(MyLock.B)
                                        {
                                               
                                                System.out.println("B    true"+(++num)+"***********");
                                        }
                                }

                        }
                }

                else
                {
                        while(true)
                        {       
                                synchronized(MyLock.B)
                                {
                                       
                                        System.out.println("B    false"+(++num)+"***********");

                                        synchronized(MyLock.A)
                                        {
                                               
                                                System.out.println("A    false"+(++num)+"***********");
                                        }
                                }

                        }
                               
                }
        }


}
上面的代码 我要说的不是可不可以产生死锁的问题  ,上面的程序肯定是可以产生死锁现象,但是在执行上面的程序 要是我多次执行该程序的话,就会有可能得到 下面这种结果:
A    true*****num=1***********
B    false*******num=1***********
就是连续两次的num的值产生了相同的结果   为什么会产生这种结果??


16 个回复

倒序浏览
他只是演示死锁又不是同步
A和B不是同一个锁,不会保证只有一个线程对num进行修改
回复 使用道具 举报
半月 发表于 2015-6-8 09:42
他只是演示死锁又不是同步
A和B不是同一个锁,不会保证只有一个线程对num进行修改 ...

你的意思我懂 但是修改num 的值得代码(++num)  和打印num 的值得代码 (System.out.println("A    false"+(++num)+"***********")) 是在一个语句中,不应该产生 连续打印出两次 一样的num 值
回复 使用道具 举报
A    true65***********
B    false65***********
B    false67***********
A    true66***********
B    false68***********
A    true68***********
B    false69***********

我试了一下,sleep了一下,竟然还有这样的情况出现。我觉得可能是因为你用了静态的num导致的,你可以试试用一个Runnable的实现类对象,不用传布尔值,直接改下判断条件,这样就可以避免静态的num了
回复 使用道具 举报
我做了小小改动,没问题了。
  1. package num_1to10;

  2. class Test {
  3.         public static void main(String[] args) {
  4.                 // Test1 test1 = new Test1(true);
  5.                 Test1 test2 = new Test1(false);

  6.                 Thread th1 = new Thread(test2);
  7.                 Thread th2 = new Thread(test2);
  8.                 th1.start();
  9.                 th2.start();

  10.         }
  11. }

  12. class MyLock {
  13.         public static final Object A = new Object();
  14.         public static final Object B = new Object();
  15. }

  16. class Test1 implements Runnable {
  17.         private boolean flag = false;

  18.         // private static int num = 0;
  19.         private int num = 0;

  20.         public Test1(Boolean b) {
  21.                 this.flag = b;
  22.         }

  23.         public void run() {

  24.                 if (this.flag) {
  25.                         this.flag = !this.flag;
  26.                         while (true) {
  27.                                 synchronized (MyLock.A) {

  28.                                         System.out.println("A    true" + (++num) + "***********");

  29.                                         synchronized (MyLock.B) {

  30.                                                 System.out.println("B    true" + (++num)
  31.                                                                 + "***********");
  32.                                         }
  33.                                 }

  34.                         }
  35.                 }

  36.                 else {
  37.                         this.flag = !this.flag;
  38.                         while (true) {
  39.                                 synchronized (MyLock.B) {

  40.                                         System.out.println("B    false" + (++num) + "***********");

  41.                                         synchronized (MyLock.A) {

  42.                                                 System.out.println("A    false" + (++num)
  43.                                                                 + "***********");
  44.                                         }
  45.                                 }

  46.                         }

  47.                 }
  48.         }

  49. }
复制代码

点评

你可以稍微描述一下他的问题在哪里  发表于 2015-6-9 14:53
回复 使用道具 举报
存在感很差 发表于 2015-6-8 12:55
A    true65***********
B    false65***********
B    false67***********

要是num 不是静态的话,那就不是两个线程的共享数据了 没有意义了!
回复 使用道具 举报
  1. System.out.println("B    false"+(++num)+"***********");
复制代码

这句话可以看一下两句话:
  1. ++num;
  2. System.out.println("B    false"+num+"***********");
复制代码

所以第一个线程执行了++num后切换到第二个线程再次++num,然后切换回去连续2次打出,所以会打出一样的
但是连续打出2个1
A    true*****num=1***********
B    false*******num=1***********
这种情况应该不会出现吧
回复 使用道具 举报
开弓没有回头箭 发表于 2015-6-8 14:08
这句话可以看一下两句话:

所以第一个线程执行了++num后切换到第二个线程再次++num,然后切换回去连续2次 ...

就是出现了连续连个1的情况
回复 使用道具 举报
Enhon1992 发表于 2015-6-8 14:49
就是出现了连续连个1的情况

没有道理呀,你这个是原代码吗,第二次打印操作之前一定会执行2次++num操作,不会出现2个1呀,出现2个二有可能的;出现2个1是不是变量没有静态哟
回复 使用道具 举报
Enhon1992 发表于 2015-6-8 13:33
要是num 不是静态的话,那就不是两个线程的共享数据了 没有意义了!

谁告诉你共享数据一定要用静态的,回去好好看看视频。
回复 使用道具 举报
哇擦擦,这么长,完全看不懂--~!
回复 使用道具 举报
我执行了楼主的源代码,确实出现了这样的情况,我和楼主的疑惑是一致的,难不成是输出语句分成了两句话
回复 使用道具 举报
mishisanyi 发表于 2015-6-9 23:29
我执行了楼主的源代码,确实出现了这样的情况,我和楼主的疑惑是一致的,难不成是输出语句分成了两句话 ...

我的猜测也是输出语句在底层是分成了2句。
回复 使用道具 举报
存在感很差 发表于 2015-6-9 22:43
谁告诉你共享数据一定要用静态的,回去好好看看视频。

我知道你的意思 但针对我的代码 要是num不是静态的话,那么两个线程操作的num 就不是同一个num了。
回复 使用道具 举报
毕老师说过,哥们飘过,我也不会 哈哈:lol
回复 使用道具 举报
Enhon1992 发表于 2015-6-10 15:51
我知道你的意思 但针对我的代码 要是num不是静态的话,那么两个线程操作的num 就不是同一个num了。 ...

所以要么让两个线程执行同一个地方的代码,那样就不会有问题。
如果非要按照你那样写静态的话,虚拟机内部是怎么样的得去问老毕了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马