多线程程序,只有一个线程在执行(卖票问题)

问题详情

见代码

public class SellTicket implements Runnable {
    private int tickets = 100;
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            try {

                lock.lock();
                if (tickets > 0) {

                    System.out.println(Thread.currentThread().getName() 
                                + "正在卖第" + tickets + "张票");
                    tickets--;
                }
            } finally {
                lock.unlock();
            }

        }
    }
}

执行 结果如下

窗口一正在卖第100张票
窗口一正在卖第99张票
窗口一正在卖第98张票

...

窗口一正在卖第3张票
窗口一正在卖第2张票
窗口一正在卖第1张票

问题解释

不知道为什么始终只有窗口一在执行代码 , 我也去网上找了答案, 告诉我是电脑硬件的问题, 现在 电脑性能越来越强了, 如果cpu性能强的话,一个线程就执行完了所有卖票操作。

我的理解

虽然网上给出了解释, 但是我硬是脑袋卡机了, 始终无法真正理解。想了半天才发现, 其实原理很简单, 就是当一个线程抢到了时间片, Windows系统下大概会执行20ms, 而cpu性能越强大, 在同样时间内一个线程就可以执行更多的指令, 也就是更多的代码, 所以第一个线程的时间片还没有执行完, 票就已经卖完了, 第二个线程根本没有参与CPU资源的竞争, 最后就导致了只有窗口一这个线程在执行。

解决办法

1. 在每次进入锁之前,将线程进行短暂休眠,从而给每个线程抢占到cpu的机会,这样也可以看到多个窗口 售卖车票的情况

                ......

                try {
                        Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
               
                lock.lock();

                ......

2. 把票数提高至10000, 这样虽然CPU性能强, 但第一个线程的时间片内也无法执行完所有卖票操作, 这样也可以看到多个窗口 售卖车票的情况

private int tickets = 10000;

 

你可能感兴趣的:(多线程,并发,java,jvm,开发语言)