问题详情
见代码
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;