你这个是把继承当实现接口用了啊,类继承像这样用是看不到与接口的区别的。要想共享资源你把你的变量ticket定义为static 静态常量就行了,我看过别人这么写过
public class SoldTicketThread implements Runnable {
private int ticket = 5;
private synchronized void sale() {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "卖出了一张票,剩余"
+ (--ticket) + "张票");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void run() {
while (ticket > 0) {
sale();
// 这里要确保进入卖票环节前就把资源锁住
}
}
public static void main(String[] args) {
SoldTicketThread window = new SoldTicketThread();
Thread wd1 = new Thread(window, "窗口二");
Thread wd2 = new Thread(window, "窗口一");
Thread wd3 = new Thread(window, "窗口三");
wd1.start();
wd2.start();
wd3.start();
}
}
你本身的逻辑就出错了,卖票的操作肯定要在循环体里面,而且要锁定的内容是整个卖票过程的操作。
是这样的 因为runnable处理同一资源也无法保证 这个资源 从加载 更改 到赋值的原子性
继承thread类和实现runnable接口本身就没有什么可比性。两者根部就不是同一类东西一个是接口,另一个是继承类且这个thread类也是继承了Runnable接口的。两者不同在于方法的实现不同,我也可以在继承thread类里写runnable的方法。再有就是java单继承的劣势,这点上Runnable会更好些。
巧合,基数5太小了,把数字改大点50000,500000,就很可能应为--操作不是原子性而出问题
这个确实是可以的啊,这个例子以前就看过,只要将票总量声明成static就可以共享了