黑马程序员技术交流社区

标题: 有关毕老师课程中多线程同步的一点小小疑问 [打印本页]

作者: 丽阳春    时间: 2016-10-31 17:16
标题: 有关毕老师课程中多线程同步的一点小小疑问
视频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的部分啊?还是我哪里理解错了……实在有些晕了,希望大家不吝赐教



作者: BugBuff    时间: 2016-11-1 12:26
因为flag不是静态的并不被多个子类对象所共享,所以在thread0中为true,thread1中为false
作者: BugBuff    时间: 2016-11-1 12:28
因为flag不是静态的并不被多个子类对象所共享,所以在thread0中为true,thread1中为false
作者: Yeauty    时间: 2016-11-3 15:13
把flag改成静态(static)就好了
作者: GXM    时间: 2016-11-3 21:43
因为是同步的,每次只能等一个线程运行完了,另外一个线程才能握到锁,

作者: wen4437    时间: 2016-11-9 15:08
首先调用t1.start()时,线程被启动执行run方法,此时flag的值为true,则进入到if中的while(true)死循环,貌似这个死循环这辈子都出不去了,因为木有终止循环的break;,并且循环里也木有判断flag,所以这就跟else毛关系都木有啦
作者: 958640368    时间: 2016-11-18 14:55
看看这张图你就能理解了,当第一个线程执行着,突然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, 下载次数: 60)

0N%IOUB{)C0]N`IL$~N}2S5.png





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2