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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Θ动@咚Θ 中级黑马   /  2013-11-14 01:46  /  1196 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这是老毕的代码:
class Ticket2 implements Runnable{
        Object obj=new Object();
        private static int ticket=200;
        boolean flag=true;
        public void run(){
                if(flag){
                while(true){
                       
                                synchronized(obj){             //1 这里上了一个obj的锁,意思线程过了这里obj的锁就锁死,即obj的状态被改为已锁状态
                                        show();                        //2 调用show方法
                        }
                }
        }
                else{
                        while(true){
                        System.out.print("else+++");
                        show();
                        }
                }
        }
       
        public synchronized void show(){               //3 this锁被改为已锁状态
                synchronized(obj){                               //4 这里的obj锁已经是已锁状态了,怎么能进去?也就是说,我的理解是,线程执行到这里已经把
                if(ticket>0){                                          //自己给锁死了。。。。
                try{Thread.sleep(10);}catch(Exception e){}
                System.out.println(Thread.currentThread().getName()+"show--------"+ticket--);
                }
                }
        }
}

public class DeadLockTest1 {
        public  static void main(String[]args){
                Ticket2 tic=new Ticket2();
                Thread t1=new Thread(tic);
                Thread t2=new Thread(tic);
                t1.start();
                try{
                Thread.sleep(10);}
                catch(Exception e){}
                tic.flag=false;
                t2.start();
        }
}


这是我的执行结果:
else+++Thread-0show--------200                      //主线程被手动sleep,确定线程0先运行,flag为true,为什么线程0会走else分支?
Thread-1show--------199
else+++Thread-1show--------198
else+++Thread-1show--------197
else+++Thread-1show--------196
else+++Thread-0show--------195
Thread-0show--------194
Thread-0show--------193
Thread-0show--------192
Thread-0show--------191
Thread-1show--------190
else+++Thread-1show--------189
else+++Thread-1show--------188
else+++Thread-0show--------187
Thread-0show--------186
Thread-0show--------185
Thread-0show--------184
Thread-0show--------183
Thread-1show--------182
else+++Thread-1show--------181
else+++Thread-1show--------180
else+++Thread-1show--------179
else+++Thread-0show--------178

我的问题是:从第一条显示结果的出的疑问,主线程被手动sleep,确定线程0先运行,flag为true,为什么线程0会走else分支?

                     还有个问题已经在程序注释中表明,随着1234步奏走就能看懂。求大神解答,我脑子笨,现在已经把我自己给锁死了。。。


点评

FFF
大脑锁不死的,我们黑马这里有钥匙。  发表于 2013-11-14 08:44

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

6 个回复

正序浏览
zuiaichiyu 发表于 2013-11-14 08:23
我的问题是:从第一条显示结果的出的疑问,主线程被手动sleep,确定线程0先运行,flag为true,为什么线程0 ...

谢谢兄弟,我添加了一些打印,自己画图走流程,算是悟了
回复 使用道具 举报
何丛 发表于 2013-11-14 08:10
在  tic.flag=false;后面加一句System.out.println(tic.flag);,看t1先执行还是main中 tic.flag=false;先 ...

谢谢姐们(如果你是姐们的话。。。),我自己画图,又添加了一些打印,自己悟了,感觉自己脑子太不够用了。。。
回复 使用道具 举报
如果问题已经解决,请及时修改主题为“提问结束”。
修改主题的方法链接
http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
我的问题是:从第一条显示结果的出的疑问,主线程被手动sleep,确定线程0先运行,flag为true,为什么线程0会走else分支?
第一个问题,sleep方法,你没有搞明白,sleep方法启动之后进入睡眠等待状态 但是依然持有执行权,一旦睡眠时间到了就可以跟t1线程抢夺cpu的资源,也就是两个线程都可以执行,sleep醒来之后程序往下执行,将flag改为false,这时候如果t1线程获得执行权,会判断flag的值,这时它是false,执行else中的内容。   
还有个问题已经在程序注释中表明,随着1234步奏走就能看懂。求大神解答,我脑子笨,现在已经把我自己给锁死了。。。
obj锁只是毕老师随意拿来用的,这里的锁跟Object没有什么关系。任意对象都可以是锁,
//1 这里上了一个obj的锁,意思线程过了这里obj的锁就锁死,即obj的状态被改为已锁状态
这句话理解不对,线程持有obj锁,并不是obj的状态改为已锁状态,obj只是线程持有的一个对象,所以第四步的时候,线程并不是把自己给锁死了

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报

在  tic.flag=false;后面加一句System.out.println(tic.flag);,看t1先执行还是main中 tic.flag=false;先执行,
有的时候是这样的结果:


说明主线程休眠的时间很短,t1执行到show方法中休眠10毫秒让出CPU的,主线程就醒了继续执行赋值操作,开启t2线程,然后t1、t2争夺CPU的执行权,刚好t2抢到了开始执行,就打印else++,然后发现两个锁都在t1手中,就等待获得锁,t2继续执行,就会出现这样的结果else+++Thread-0show--------200,LZ请注意”else+++Thread-0“而不是“else+++Thread-1”
第二个问题
Object obj = new Object();
        synchronized(obj){
            for(int i=0; i<10; i++){
                System.out.println("i:"+i);
                if(i==5){
                    synchronized(obj){
                        System.out.println("hello");
                    }
                }
            }
执行结果是

可见锁定了obj后在本对象里再次获取这个锁不会出现死锁

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马