楼主: sinkeler

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

[复制链接]
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
11#
 楼主| 发表于 2008-2-13 14:27 | 只看该作者
辛苦,麻烦你把你的log代码给我看一下,或者看一下源码,你在什么地方加的日志

使用道具 举报

回复
论坛徽章:
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
12#
发表于 2008-2-13 14:29 | 只看该作者

就是加的System.out.println(), 这里。。。

public class Transfer {

                public static void main(String[] args) throws Exception
        {
                Record r1 = new Record();
                Record r2 = new Record();
                doTransfer( r1, r2, 5 );
                doTransfer( r2, r1, 2 );
                doTransfer( r1, r2, 1 );
               
                //print the result
                //System.out.println( "r1 = " + r1.get() + " r2 = " + r2.get() );
        }
        
        private static void doTransfer(final Record a, final Record b, final int amount)
        {
                Thread t = new Thread()
                {
                        public void run()
                        {
                                new Clerk().transfer(a, b, amount);
                        }
                };
                                
                t.start();
        }
}

class Clerk
{
        public synchronized void transfer(Record a, Record b, int amount)
        {
                synchronized(a)
                {
                        System.out.println("**********start synchronized(a)****************");
                                                synchronized(b)
                        {
                                System.out.println("**********start synchronized(b)****************");
                                                                a.add( -amount );
                                                                //System.out.println("after a.add num="+num);
                                                                System.out.println("            a.get()="+a.get());
                                b.add( amount );
                                                               
                                                                //System.out.println("after b.add num="+num);
                                                                System.out.println("            b.get()="+b.get());
                                                                System.out.println("**********end synchronized(b)****************");
                                
                        }

                }
                                System.out.println("**********end synchronized(a)****************");
        }
}

class Record
{
        
        int num = 10;
        
        public int get()
        {
                return this.num;
        }
        
        public void add(int n)
        {
                System.out.println("num = num + n="+"="+num+"+"+n);
                                num = num + n;
                               
                                System.out.println("                    num="+num);
        }
}

使用道具 举报

回复
论坛徽章:
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
13#
发表于 2008-2-13 14:29 | 只看该作者
但是实际上我觉得也不能相信System.out.println()的结果,因为这个顺序也是不保证的阿。。。这也是飘忽不定的,你看r1=5,r1=15的结果的位置就是飘忽不定的,啊哈

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

使用道具 举报

回复
论坛徽章:
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
14#
发表于 2008-2-13 14:32 | 只看该作者

终于得到一次没有deadlock的结果,激动啊

E:\>java Transfer
**********start synchronized(a)****************
**********start synchronized(b)****************
num = num + n==10+-5
                    num=5
            a.get()=5
num = num + n==10+5
                    num=15
            b.get()=15
r1 = 5 r2 = 15
**********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
**********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
**********end synchronized(b)****************
**********end synchronized(a)****************

使用道具 举报

回复
论坛徽章:
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
15#
发表于 2008-2-13 14:35 | 只看该作者

n次deadlock的结果都是r1=10,r2=10

E:\>java Transfer
r1 = 10 r2 = 10
**********start synchronized(a)****************
**********start synchronized(b)****************
num = num + n==10+-5
                    num=5
            a.get()=5
num = num + n==10+5
                    num=15
            b.get()=15
**********end synchronized(b)****************
**********start synchronized(a)****************
**********start synchronized(a)****************
**********end synchronized(a)****************


dead了!!!

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
16#
 楼主| 发表于 2008-2-13 14:37 | 只看该作者
我用eclipse,也老是10和10,然后就不走了

使用道具 举报

回复
论坛徽章:
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
17#
发表于 2008-2-13 14:39 | 只看该作者
aaaaaaaaaaaaaa忽然发现忘记一个重要的thread!!!main的阿!!!System.out.println(r1.get())是在main里面!!!所以main的语句被执行也是飘忽不定的!!!

我又错了。。。。

结果不同是由于main里面System.out.println()的执行时间!!!而不是因为num的问题!!!!

使用道具 举报

回复
论坛徽章:
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
18#
发表于 2008-2-13 14:40 | 只看该作者
我得到一次不deadlock的结果,你看看!在上面,能看出一些问题了。。。。

a.add()
b.add()

是被保证了的。。。

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

使用道具 举报

回复
论坛徽章:
3
生肖徽章2007版:牛
日期:2008-09-25 19:22:372009新春纪念徽章
日期:2009-01-04 14:52:28生肖徽章2007版:狗
日期:2009-01-14 14:14:37
19#
 楼主| 发表于 2008-2-13 14:42 | 只看该作者
呵呵,不知道这样能不能解释通,因为synchronized已经给a和b上锁了,所以get和add方法也没有必要上锁,反正一次就一个线程访问对象

使用道具 举报

回复
论坛徽章:
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
20#
发表于 2008-2-13 14:50 | 只看该作者
我的理解是
对象a和b得到锁了,那么自然它们调用的方法也该被锁了

然后由于main thread里面的
doTransfer( r1, r2, 5 );  thread1 建立了自己的stack
doTransfer( r2, r1, 2 );  thread2 建立了自己的stack
doTransfer( r1, r2, 1 ); thread3 建立了自己的stack

         
                //print the result
System.out.println( "r1 = " + r1.get() + " r2 = " + r2.get() ); 属于thread main 有自己的stack

总共4个thread,谁也不保证谁,每个thread值保证自己的方法执行。。。互相交错。。。。。但是由于thread1 thread2 thread3操作的就是两个有锁的对象a.b所以之间要互相通信,这个放了索,那个就要得到索,但是thread main是相对独立的,什么时候scheduler调他了,他就执行,不需要什么锁,不需要等待////

使用道具 举报

回复

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

本版积分规则 发表回复

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