黑马程序员技术交流社区

标题: 多线程同步的问题 [打印本页]

作者: 淡夜清风    时间: 2014-1-13 07:36
标题: 多线程同步的问题
class Ticket implements Runnable{

        private int tick = 1000;
        public synchronized void run() {
                while(true){
                        if(tick>0){
                                try {
                                        Thread.sleep(10);
                                        System.out.println(Thread.currentThread().getName()+"...sale"+tick--);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                               
                }
        }
       
}

public class ThisLockDemo {

        public static void main(String[] args){
                Ticket t = new Ticket();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }
}
输出结果:
Thread-0...sale1000
Thread-0...sale999
Thread-0...sale998
Thread-0...sale997
Thread-0...sale996
Thread-0...sale995
Thread-0...sale994
....

这个程序怎么老是一个线程在执行?为什么会这样?
--------------------------------------------------------------------

class Ticket2 implements Runnable{

        private int tick = 1000;
        public void run() {
                while(true){
            show();
                }
        }
       
        public synchronized void show(){
                if(tick>0){
                        try {
                                Thread.sleep(10);
                                System.out.println(Thread.currentThread().getName()+"...sale"+tick--);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }
       
}

public class ThisLockDemo2 {

        public static void main(String[] args){
                Ticket2 t = new Ticket2();
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
        }
}

输出结果:
....
Thread-0...sale988
Thread-0...sale987
Thread-0...sale986
Thread-0...sale985
Thread-3...sale984
Thread-3...sale983
Thread-3...sale982
Thread-3...sale981
Thread-3...sale980
....
这个程序我感觉和上面程序差不多啊。为什么这个程序是4个线程交替执行的?和上面程序有什么差别?
作者: 爱上这格调    时间: 2014-1-13 09:12
看一下你的代码   第一个把while循环也同步进去了   结果就是一个线程拿到锁之后进进入while
循环  之后不断循环直到循环结束   程序也就结束了   别的线程拿不到锁  当然就只有一个线程在执行了
作者: 淡夜清风    时间: 2014-1-13 09:38
查找了下资料,我的个人理解,不足之处欢迎指正。。
第一个程序:
public synchronized void run() {
                while(true){
                        if(tick>0){
                                try {
                                        Thread.sleep(10);
                                        System.out.println(Thread.currentThread().getName()+"...sale"+tick--);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                        }
                               
                }
        }

把run()方法给锁住了,线程只有拿到锁才能执行run方法。
当一个线程拿到锁后,运行run()方法。等到run()方法执行结束后才会释放锁,别的线程才有机会拿到锁。但是run()方法里面有一个while(true)死循环,方法永远也不会执行完,所以永远也不会释放锁,所以就只有一个线程在执行,其他线程都在等待。(本来误认为sleep会释放锁,其实sleep只是线程休眠,不会释放锁)
------------------------------
第二个程序:
public synchronized void show(){
                if(tick>0){
                        try {
                                Thread.sleep(10);
                                System.out.println(Thread.currentThread().getName()+"...sale"+tick--);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }
把show()方法给锁住了,线程只有拿到锁才能执行show方法。
show方法是可以执行完的,所以每个线程都有机会拿到锁,执行show()方法。
这个程序每循环一次,线程都重新得到锁、释放锁。。。
作者: 刘旭升    时间: 2014-1-13 09:40
都是synchronized惹的祸!{:soso_e127:}
第一个程序你自己看代码走一边会发现:当第一个线程A运行run方法时,其他的程序由于run方法是synchronized的,所以要等进去的那个线程执行完毕。但是你看看你写的那个run方法,while(true),得了第一个线程进去就直接把1000票全干掉了(这里你可以把设置sleep(4000),观察效果。)。没票了,A线程出来,其他的线程可以进去,但是没票了。。。解决办法:其实有很多的。
①去掉run方法的synchronized。因为你设置了sleep(),时间还好。会出现交替售票。
②将while改为if,就是让线程可以进去又出得来,只是没有了循环,这个问题就留给你了。{:soso_e179:}

作者: xu6148152    时间: 2014-1-13 09:50
第一个进程一进入while(true)这个条件永远满足,因此会在里面死循环。所以只会有有一个进程执行。
用synchronized()不是更好,不要直接整个函数都是synchronized.




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