楼主: sinkeler

[SCJP] 关于线程同步的一道题

[复制链接]
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
21#
发表于 2008-2-13 14:58 | 只看该作者
所以main thread打印thread1的结果,或者打印thread2的结果,或者打印thread3的结果。。。。所以这三个thread的结果是一定的。。。。main thread只是3选一而已。。。

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
22#
 楼主| 发表于 2008-2-13 15:21 | 只看该作者
我有点明白了

重点分析这一块

synchronized(a)
{
      synchronized(b)
     {
           a.add( -amount );
           b.add( amount );
      }
}


对于实际情况是这样

                                                      
synchronized(r1)                                synchronized(r2)
{                                                        {
       synchronized(r2)                                 synchronized(r1)
      {                                                          {
            r1.add( -amount );                                 r2.add( -amount );

            r2.add( amount );                                  r1.add( amount );
       }                                                          }
}                                                         }

Record r1 = new Record();
Record r2 = new Record();
doTransfer( r1, r2, 5 ); // line 1
doTransfer( r2, r1, 2 ); // line 2
doTransfer( r1, r2, 1 ); // line 3

我们假定以下情况:

A)、line1 执行,则执行到上面的,在执行完synchronized(r1) 以后,没准就执行了中的synchronized(r2),剩下的情况就是死锁;

B)、line 1 执行,执行到,等待r2和r1的锁释放后,即全部执行完,r1.num = 5,r2.num = 15,这是选项B。接着:
     
    *  此时line 2被执行,可能被运行,此时
        r2.num = 13,r1.num = 7,这种情况很好理解,就是按顺序获得锁,然后执行,只不过没有这个选项;
        
        *  接下来,line 3被执行,于是r1.num = 6,r2.num = 14,所以得到选项A,整个程序执行完毕;

[ 本帖最后由 sinkeler 于 2008-2-13 15:48 编辑 ]

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
23#
发表于 2008-2-13 15:53 | 只看该作者
偶觉得不是阿
一共可是4个thread,是这4个thread在互相等待执行哦。。。。。
你的甲乙还要在加上一个丙哦,另外还有一个thread main(String[] a){System.out.println(a.get.....)}....

甲乙丙都会好好的执行滴,thread main要是在甲后执行,就打印甲的结果,否则就是乙的结果或者是丙的结果。。。。。

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
24#
 楼主| 发表于 2008-2-13 15:59 | 只看该作者
我明白你指的是什么,不过刚好可以解决这个问题

总共3个thread

按我上面的说法可以将其分成3段执行,即

1)r1.num = 5,r2.num = 15
2)r2.num = 13,r1.num = 7
3)r1.num = 6,r2.num = 14

根据main的第4个主thread,可以想象一下System.out.println可以任意取出其中一段来输出,而不是3段都执行完才能输出,这样结果只能由一个,即最后的r1.num = 6,r2.num = 14。

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
25#
发表于 2008-2-13 16:00 | 只看该作者

这么说吧,Roger?

原帖由 silver_xie 于 2008-2-13 14:32 发表
E:\>java Transfer
**********start synchronized(a)****************
**********start synchronized(b)****************
num = num + n==10+-5
                    num=5
            a.get()=5                                                             (thread1 的结果:doTransfer( r1, r2, 5 );)
num = num + n==10+5
                    num=15
            b.get()=15
r1 = 5 r2 = 15(注意main thread在这里执行了System.out.println(XXXXX);不幸打印了thread1的结果)main thread也可能在thread2后出现,那么就打印thread2,还有可能是thread3的。。。。
**********end synchronized(b)****************
**********start synchronized(a)****************
**********start synchronized(b)****************
num = num + n==15+-2
                    num=13
            a.get()=13
num = num + n==5+2
                    num=7
            b.get()=7                                                          (thread2 的结果:doTransfer( r1, r2, 2 );)
**********end synchronized(b)****************
**********end synchronized(a)****************
**********end synchronized(a)****************
**********start synchronized(a)****************
**********start synchronized(b)****************
num = num + n==7+-1
                    num=6
            a.get()=6
num = num + n==13+1
                    num=14
            b.get()=14                                                         (thread3的结果:doTransfer( r1, r2, 1 );)

**********end synchronized(b)****************
**********end synchronized(a)****************


重点是 对象a(r1),b(r2)互相不影响,也就是对象a的num只被a.add()影响,b的num只被b.add()影响

[ 本帖最后由 silver_xie 于 2008-2-13 16:06 编辑 ]

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
26#
 楼主| 发表于 2008-2-13 16:00 | 只看该作者
我说的甲乙,是指总共就两种情况,虽然说是3个thread,第一个和第三个thread都是用的甲这种情况

使用道具 举报

回复
论坛徽章:
8
开发板块每日发贴之星
日期:2007-12-23 01:06:08开发板块每日发贴之星
日期:2007-12-24 01:05:56开发板块每日发贴之星
日期:2007-12-27 01:05:492008新春纪念徽章
日期:2008-02-13 12:43:03开发板块每日发贴之星
日期:2008-02-14 01:02:08开发板块每日发贴之星
日期:2008-02-15 01:05:13开发板块每日发贴之星
日期:2008-02-16 01:06:48开发板块每日发贴之星
日期:2008-02-17 01:05:20
27#
发表于 2008-2-13 16:01 | 只看该作者

不是刚好那么简单吧????

我觉得是synchronized保证了这样的结果哦,保证了,必然哦,因为我得到了不是deadlock的结果,可以验证我的想法哦。

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
28#
 楼主| 发表于 2008-2-13 16:01 | 只看该作者
对了,配合你的输出结果,我的理论就对了

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
29#
 楼主| 发表于 2008-2-13 16:03 | 只看该作者
你可以观察到,你的output里只有一句话是System,其实这句话可以放在thread2或者thread3后

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
30#
 楼主| 发表于 2008-2-13 16:03 | 只看该作者
这下应该通了

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表