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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

丽阳春

初级黑马

  • 黑马币:10

  • 帖子:7

  • 精华:0

5黑马币
视频138中讲到一个例子,为了验证同步函数的锁是this使用了以下代码
class Ticket implements Runnable// extends Thread
{
        private int tick = 1000;

        Object obj = new Object();

        boolean flag = true;

        public void run()
        {
                if (flag)                                                                                                //当flag=true时,线程执行同步代码块
                        while(true)
                        {
                                synchronized(obj)
                                {
                                        if (tick>0)
                                        {
                                                try{Thread.sleep(10);}catch(Exception e){}//强制线程睡眠,使运行出现溢出错误
                                                System.out.println(Thread.currentThread().getName()+" ...code...:"+tick--);
                                        }
                                }
                    }
                else                                                                                                        //当flag=false时,线程执行同步函数
                        while (true)
                        {
                                show();
                        }
        }

        public synchronized void show()
        {
                if (tick>0)
                {
                        try{Thread.sleep(10);}catch(Exception e){}//强制线程睡眠,使运行出现溢出错误
                        System.out.println(Thread.currentThread().getName()+" ...show:"+tick--);
                }
        }
}

class ThisLockDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();
               
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);

                t1.start();
                t.flag = false;       //切换flag为false
                try{Thread.sleep(10);}catch(Exception e){}
                t2.start();

        }
}



结果如上图,大致就是让两个线程各自运行run()方法中flag=true与flag=false的部分。
我的疑惑就是,为什么thread-0能一直运行flag=true时的同步代码块?如果thread-1已经运行了,代表flag已经被改为false了吧,那么thread-0再运行run()方法时应该也运行false的部分啊?还是我哪里理解错了……实在有些晕了,希望大家不吝赐教


6 个回复

倒序浏览
因为flag不是静态的并不被多个子类对象所共享,所以在thread0中为true,thread1中为false
回复 使用道具 举报
因为flag不是静态的并不被多个子类对象所共享,所以在thread0中为true,thread1中为false
回复 使用道具 举报
把flag改成静态(static)就好了
回复 使用道具 举报
因为是同步的,每次只能等一个线程运行完了,另外一个线程才能握到锁,
来自宇宙超级黑马专属苹果客户端来自宇宙超级黑马专属苹果客户端
回复 使用道具 举报
首先调用t1.start()时,线程被启动执行run方法,此时flag的值为true,则进入到if中的while(true)死循环,貌似这个死循环这辈子都出不去了,因为木有终止循环的break;,并且循环里也木有判断flag,所以这就跟else毛关系都木有啦
回复 使用道具 举报
看看这张图你就能理解了,当第一个线程执行着,突然cpu把资源分给第二个线程后,第二个线程的状态为Runing,第一个线程会进入Runable,从图可以看出Runable在start后面,也就是说线程的start只会启动一次,它里面的数据一直是start启动时的数据(但run方法里数据会随着变化而变化),cpu让线程暂停会让线程进入Runing状态。而不是从新开始,除非这个线程执行完了,或抛出异常了,那他就真的停止了,在开始就是从start开了。(你从显示的结果也能看出来,如果他从每次让出资源时后都从start开始的话,那么你会看到显示的数都是从100开始到一个数,然后后面又是从100开始,因为start开始就是从原始数据开始。你从结果看显然不是这种情况,他显示的数据都是依次从100到最后,好像这里面有个东西记录着执行到哪了,这说明没真正的停止而是进入Runing状态了,等第二个线程让出资源,然后他会在进入Runing状态)

0N%IOUB{)C0]N`IL$~N}2S5.png (56.12 KB, 下载次数: 62)

0N%IOUB{)C0]N`IL$~N}2S5.png
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马