黑马程序员技术交流社区

标题: 多线程--对比一下代码区别--代码2多打印了3个40 [打印本页]

作者: 江南小道士    时间: 2014-11-20 03:15
标题: 多线程--对比一下代码区别--代码2多打印了3个40
class TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t1 = new Ticket();
                Ticket t2 = new Ticket();
                Ticket t3 = new Ticket();
                Ticket t4 = new Ticket();

                t1.start();
                t2.start();               
                t3.start();
                t4.start();
        }
}

class Ticket extends Thread
{
        private static int tick = 40;
        public void run()
        {
                while(tick>0)
                {
                        System.out.println(currentThread().getName()+"sale :"+tick--);//代码1:这里做自减动作,运行结果正常:40 39 38 37 ...
                        //tick--;//代码2:假如上一条输出语句不做自减动作,这里再自减,结果会打印4个40,然后才打印39 38 37 36 ...        也就是多打印了3个40
                }
        }
}

有大神能解释一下吗?
作者: zhangyangLengen    时间: 2014-11-20 08:42
因为这样,出现线程的安全隐患,每次当运行到  ticket-- 时线程就会被切换,此时ticket还是40,并没有进行自减。如果出现几次这样的情况,就会出现几次40的情况
作者: 江南小道士    时间: 2014-11-20 23:18
zhangyangLengen 发表于 2014-11-20 08:42
因为这样,出现线程的安全隐患,每次当运行到  ticket-- 时线程就会被切换,此时ticket还是40,并没有进行 ...

貌似有点道理~~
作者: 江南小道士    时间: 2014-12-3 05:22
class TicketDemo
{
        public static void main(String[] args)
        {
                Ticket t1 = new Ticket();
                Ticket t2 = new Ticket();
                Ticket t3 = new Ticket();
                Ticket t4 = new Ticket();
                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}
class Ticket extends Thread
{
        private static int tick = 40;
        Object obj = new Object();
        public void run()
        {
                while(tick>0)
                {
                        synchronized(obj)
                        {
                                System.out.println(currentThread().getName()+"sale :"+tick);
                                tick--;
                        }
                }
        }
}
这里加了同步,结果还是多打印了三个40.。。。。会不会是因为 tick 是静态的关系?
作者: kane    时间: 2014-12-3 16:42
楼主,不是静态的问题,每一个线程进来都会打印40次,也就是说会打印4个40次,必须保证所以线程都从一个40里面减去卖出的票。比如,实现Runable接口,并复写run()方法。这样就保证他们4个线程都只访问同一个40,从而实现同步卖票。
//多线程,4个线程同时买票,同时解决安全问题(synchronized锁)

class Ticket implements Runnable
{
        private int i=100;
        Object obj=new Object();
               
        public void run()
        {
                while(true)
                {
                        synchronized(obj)
                        {
                                if(i>0)
                                {
                                        try
                                        {
                                                Thread.sleep(10);
                                        }
                                        catch(InterruptedException ie){}
                               
                                        System.out.println(Thread.currentThread().getName()+"------sale: "+ i--);
                                }
                        }
                }
        }
}


class TicketDemo
{
        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();
        }
}






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