你把票数调多点,把ticket设置成1000试试
从理论上来说,三个线程各自用自己的 Object 对象作为锁,是不存在互斥等待锁的,代码这样是有问题的。
Object object 对象应该由外部调用类传入,然后三个线程竞争该锁完成售票过程。
其次,休眠时间太短了,线程 1 先创建并启动,所以表象是它一直在运行,把 sleep 调大就能看到间或运行了。
真的很难想象
找到原因了:
线程之所以能并发执行是因为cup对时间进行了拆分,比如前10ns执行线程1、再过10ns执行线程2、再过11ns执行线程1、再过9ns执行线程3...(线程和时间都是随机的,大致是这样)。假设线程执行售票操作用时一直都是10001ns,执行过程大致如下:
1.main函数执行,并初始化3个thread。
2.3个线程先后start。
3.由于线程1先start的,所以基本上都是先执行(偶尔抽风可能就不是他了),这样的话线程2、线程3都会进入阻塞。
4.在cpu里面大致就是线程1售票操作10ns、线程2阻塞了10ns、线程1又售票操作11ns、线程3阻塞9ns...
5.当执行n次循环后,售票操作执行了10000ns了,这时线程1开始执行了,当他执行1ns时,第一次售票操作完并释放锁,但并没有轮到线程2执行,因为线程1还有时间呢,所以继续while(true)然后加锁,然后就这样线程1又开始了第二次售票,当执行了9ns后,时间片切换,轮到线程2执行了,但线程2发现又tm锁住了,只能继续等待以此往复...
6.突然当执行第88次售票结束时,线程1刚好用完他的时间片,这时轮到线程3然后很邪恶的说:我也要这样玩下去...
所以要想看到效果有一下2种方案:
1.把ticket改成10000就可以看到:线程11111...线程333333...线程22222... ...
2.在synchronized之外随便加上几行无用的代码就可看到:线程1232312313123212...
因为synchronized是非公平锁导致你有可能只会看到一个线程在执行,你可以把synchronized换成一个公平锁(new ReentrantLock(true))肯定能看到你要的效果