チケットを販売するためのグローバル変数がある単純な問題を実装しようとしています。10 枚のチケットを販売するために 3 つのスレッドを生成します。これは、バイナリ セマフォを使用して行っています。
private static int noOfTickets =10;
private static boolean soldAll = false;
private static Random r = new Random(10);
/************ MAIN **************/
public static void main(String[] arg){
// spawn 10 threads to see a tickets
for(int i =0; i<3; i++){
Thread t = new Thread(new sellRunnable());
t.setName("Me_"+i);
t.start();
}
}
/************ MAIN **************/
public static void sell() throws InterruptedException{
Semaphore b = new Semaphore(1);
int numOfTicketsSoldByThisThread = 0;
while(!soldAll){
addRandomDelay(1000, 100);
b.acquire();
if(noOfTickets>0){
Thread t = Thread.currentThread();
numOfTicketsSoldByThisThread++;
noOfTickets--;
System.out.println("I "+t.getName()+" sold "+numOfTicketsSoldByThisThread+"ticket. tickets left are "+noOfTickets);
}else{
soldAll = true;
System.out.println(" sold all tickets");
}
b.release();
}// end of while
}
public static class sellRunnable implements Runnable{
public void run() {
try {
sell();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
このコードを実行すると、正しい出力が得られません。ある時点でこれが得られます
- I Me_2 は 1 チケットを売りました。チケットは残り7枚
- I Me_1 は 1 チケットを売りました。チケットは残り7枚
残りのチケットが 7 であることを 2 つのスレッドが出力していることに注意してください。それは正しくありませんか?noOfTicketsLeft-- はアトミック操作ではなく、セマフォ内にあることはわかっています。それで、それはうまくいくはずですか?