今天学了多线程,说在下面这个案例中如果不加锁的话,容易出现线程安全问题。所以我尝试了把多线程共享的tickeNumbers
加了锁,目的是每个线程执行到此处代码时会先看tr对象的这个tickeNumbers
变量有没有锁,如果没有就进入同步代码块中执行操作,否则就等待,这样就解决了同一张票卖多次的问题,但实际多执行几次后发现,还是会出现这种现象(),有能帮忙分析下原因的嘛
public class Demo01 {
public static void main(String[] args) {
TicketRunnable tr = new TicketRunnable();
for (int i = 0; i < 4; i++) {
Thread t = new Thread(tr,"窗口"+(i+1));
t.start();
}
}
}
class TicketRunnable implements Runnable{
Integer tickeNumbers = 100;
@Override
public void run() {
String name = Thread.currentThread().getName();
while(true){
synchronized(tickeNumbers){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickeNumbers <= 0) {
System.out.println("票卖光了");
break;
}
System.out.println(name + "售出:(" + (tickeNumbers--) + ")");
}
}
}
}
实际执行结果(出现问题的一次):
窗口1售出:(100)
窗口1售出:(99) //此处99号票被卖了两次
窗口4售出:(99)
窗口3售出:(97)
窗口1售出:(98)
窗口2售出:(96)
窗口3售出:(94)
窗口4售出:(95)
窗口3售出:(93)
窗口1售出:(92)
窗口2售出:(91)
窗口2售出:(90)
窗口4售出:(89)
窗口1售出:(87)
窗口3售出:(88)
窗口4售出:(86)
窗口2售出:(86)
窗口4售出:(85)
窗口3售出:(84)
窗口2售出:(83)
窗口4售出:(82)
窗口1售出:(83)
窗口2售出:(81)
窗口4售出:(80)
窗口3售出:(81)
窗口2售出:(79)
窗口1售出:(79)
窗口2售出:(78)
窗口3售出:(78)
窗口4售出:(77)
窗口1售出:(76)
窗口2售出:(75)
窗口1售出:(74)
窗口3售出:(72)
窗口2售出:(73)
窗口4售出:(74)
窗口1售出:(71)
窗口4售出:(70)
窗口1售出:(69)
窗口4售出:(68)
窗口1售出:(67)
窗口2售出:(67)
窗口4售出:(66)
窗口3售出:(65)
窗口1售出:(65)
窗口4售出:(64)
窗口2售出:(63)
窗口3售出:(62)
窗口4售出:(61)
窗口1售出:(60)
窗口2售出:(60)
窗口3售出:(60)
窗口4售出:(59)
窗口1售出:(58)
窗口4售出:(57)
窗口2售出:(56)
窗口1售出:(55)
窗口4售出:(54)
窗口1售出:(53)
窗口2售出:(52)
窗口3售出:(51)
窗口4售出:(50)
窗口1售出:(49)
窗口2售出:(48)
窗口3售出:(47)
窗口4售出:(46)
窗口1售出:(45)
窗口3售出:(44)
窗口4售出:(43)
窗口2售出:(42)
窗口1售出:(42)
窗口3售出:(41)
窗口4售出:(40)
窗口2售出:(39)
窗口3售出:(38)
窗口4售出:(37)
窗口2售出:(36)
窗口1售出:(36)
窗口3售出:(35)
窗口4售出:(34)
窗口2售出:(33)
窗口3售出:(32)
窗口4售出:(31)
窗口2售出:(30)
窗口1售出:(30)
窗口3售出:(29)
窗口4售出:(28)
窗口2售出:(27)
窗口3售出:(26)
窗口4售出:(25)
窗口2售出:(24)
窗口1售出:(24)
窗口3售出:(23)
窗口4售出:(22)
窗口2售出:(21)
窗口3售出:(20)
窗口4售出:(19)
窗口1售出:(18)
窗口2售出:(18)
窗口3售出:(17)
窗口4售出:(16)
窗口1售出:(15)
窗口3售出:(14)
窗口4售出:(13)
窗口1售出:(12)
窗口2售出:(11)
窗口3售出:(10)
窗口4售出:(9)
窗口1售出:(8)
窗口3售出:(7)
窗口4售出:(6)
窗口2售出:(5)
窗口1售出:(5)
窗口3售出:(4)
窗口4售出:(3)
窗口2售出:(2)
窗口3售出:(1)
票卖光了
票卖光了
票卖光了
票卖光了
Process finished with exit code 0