搜索
在java开发中为什么这个synchronized锁不住那三个线程?
高洛峰
高洛峰 2017-04-17 13:51:57
[Java讨论组]
public class Demo10_5 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
//定义三个售票窗口
        TicketWindow tw=new TicketWindow();

        //使用三个线程同时启动
        Thread t1=new Thread(tw);
        Thread t2=new Thread(tw);
        Thread t3=new Thread(tw);

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


    }

}

class TicketWindow implements Runnable{
    //一共两千张票
    private  int nums=2000;
    private Dog myDog=new Dog();

    @Override
    public void run() {
        // TODO Auto-generated method stub

            while(true){

//认为if else 要保证其原子性
                synchronized (myDog) 
                {
                    //判断是否还有票
                    if(nums>0){

                        //显示售票信息
                        //Thread.currentThread().getName()当前线程的名字
                    System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"票");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        nums--;
                        }else {
                        //售票结束
                        break;
                    }
                }



                }
            }
    }

class Dog{

}
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(3)
黄舟

非常抱歉,没能及时更新这个问题的答案。

后面我自己解决了这个问题。

我干了这么一件事情。

我初始化了一个窗口,安排了2000张卖票,然后安排三个工作人员卖票(三个线程)一起卖票(同时访问我设置的2000张票)。

其实这个我想问的是,为什么不能按照t1线程先卖,t2线程后卖,t3再买。

后面我想了,应该是操作系统的问题,线程的优先级不同。应该是不能按照顺序去卖这个票。

就和我们去买票的时候是一样的,随机的三个卖票的,是随机的,而不能按照顺序。

如果非要按照顺序的话,那么用一个线程就够了,何必要用多线程。

结论就是,完全锁住了,没有出现三个线程同时卖一张票的情况。

结果截图:

黄舟

先说为什么三个线程没同步:
因为,没有什么需要同步的。
我猜测你的目的是三个线程同步售出2000张票。
程序中票数是TicketWindow的一个成员变量,而三的线程中各有一个TicketWindow实例。所以三个2000是互不相干的。
最简单的方式是把票数改为static,这样所有TicketWindow实例到使用同一个类成员变量。当然用来锁的dog也需要改为static。

后面是建议:
不要使用new thread方式写多线程,请参考Java concurrent包中Callable等类,在较高抽象级别处理多线程。

最后的建议:
练手写写无所谓,如果是真正要用的代码,不要写多线程同步逻辑!
找可靠的第三方库或者软件来处理。

阿神

你这么写没问题啊... 三个线程是在卖2000张票.. 而且是一张一张卖的, 也没重复卖..
不知道你是要问什么问题...
执行的时候, 三个线程不会是顺序来卖票的, 因为cpu的时钟选择哪个是不确定的... 如果你想要顺序卖的话, 逻辑就得都改一下了...
其他的答案... 你们确定看清楚别人是怎么写的了么... 锁是对的, 2000张票也是对的...

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号