public class Counter {
private int count = 0;
public Counter(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void reduce() {
this.count --;
}
}
首先计数器类,模拟火车卖票计数器。
public class SellThread extends Thread{
Counter counter ;
public SellThread(Counter counter ) {
this.counter = counter;
}
@Override
public void run() {
while(counter.getCount() > 0) {
int c = counter.getCount();
counter.reduce();
System.out.print(String.format("%s正在卖票:共%d张票,卖出一张,剩余%d张 \n",super.getName(),c, counter.getCount()));
}
}
这个是卖票的线程,如果计数器里的count 大于0 就一直卖直到卖完为止。
public class Test {
public static void main(String[] args) {
Counter counter = new Counter(1000);
Thread thread1 = new SellThread(counter);
Thread thread2 = new SellThread(counter);
Thread thread3 = new SellThread(counter);
Thread thread4 = new SellThread(counter);
Thread thread5 = new SellThread(counter);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
}
}
这是测试类,开启五个线程卖票,相当于是开了五个窗口同时卖票。现在运行一下,结果如下
因为卖票的操作不是一个原子操作,所以出现这样的问题,步骤大概是
1.读取当前的票数
2.当前票数减1
3.把减少后的票数再赋给计数器
改进了一下之后,发现效果是实现了,但是好像所有的票都是由第一个线程在卖。这个锁应该是GG了,毛病。
然后又改进了一下,吧锁放在循环里面,发现,他进循环的时候count都是大于0的,但是进去只有其他的窗口把票卖完了,然后这边还不知道,还在卖。。。这就又GG了。
然后又改进了下卖票的方法,貌似效果是达到了,五个窗口同时卖票,并且卖完就不能卖了。但是我知道这肯定是有毛病。
这个还得再想想办法,这样太low了。
刚刚又写了几个demo,突然发现是自己二笔了。我就纠结为毛总是多了五次循环卖,但是又没票。
突然发现我开了五个线程去卖,当其中一个线程发现票卖完了的时候,这个循环break了。这个锁释放了,
但是其他的四个线程while还在执行,所以他要每一个都判断了 count <= 0 然后结束循环。我还纠结半天
emmmmmm,二笔了。其实在Counter里reduce方法里锁一下就行了。