Java多執行緒實現視窗售票的功能
阿新 • • 發佈:2019-01-06
在這個程式中我們一共售賣1-100號票,一共有4個視窗,首先我們看程式如下
package com.study.article1;
/**
* @func 多執行緒實現視窗賣票.
* @author 張俊強~
* @time 2017/10/27 12:52
* */
class Ticket implements Runnable {
private int ticket = 1000;
public void salesTickets() {
synchronized (this) { //加同步鎖
if (ticket > 0) { //再次判斷是否還有餘票
System.out.println(Thread.currentThread().getName() + "正在賣第[ " + ticket-- + " ]張票...");
}
}
}
public void run() {
while (ticket > 0) { //當還有餘票的時候繼續賣票
salesTickets(); //呼叫賣票方法
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TicketDemo {
public static void main(String[] args) {
Ticket t = new Ticket();
Thread w1 = new Thread(t,"視窗一");// 建立四個視窗
Thread w2 = new Thread(t,"視窗二");
Thread w3 = new Thread(t,"視窗三");
Thread w4 = new Thread(t,"視窗四");
w1.start();
w2.start();
w3.start();
w4.start();
}
}
針對以上的程式做一下兩點說明
(1).為什麼要加同步鎖synchronized (this)
?
如果不加同步鎖的話會出現這樣子的情況(只舉一個例子)
public void salesTickets() {
//synchronized (this) { //加同步鎖
//if (ticket > 0) {
// 這裡標誌位 【位置一】
System.out.println(Thread.currentThread().getName() + "正在賣第[ " + ticket-- + " ]張票...");//【賣票操作】
// 這裡標誌位 【位置二】
//}
//}
}
當票庫中只有一張票的時候,一號執行緒走到了【位置一】
再他剛準備執行【賣票操作】的時候,二號執行緒走到了【位置一】(沒有加鎖就可以進來)
這時候一號執行緒賣完了票ticket=0
,二號執行緒就把第零張票給賣出去了
(2).為什麼要兩次判斷是否還有餘票?
有的同學就會有疑問,我加一個同步鎖就是啦,為什麼還要兩次判斷是否還有餘票呢?
public void run() {
while (ticket > 0) { //當還有餘票的時候繼續賣票
// 這裡標誌為 【位置一】
salesTickets(); //呼叫賣票方法
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
當票庫中只有一張票的時候,一號執行緒走到了【位置一】
再他剛準備執行【呼叫賣票方法】的時候,二號,三號執行緒都走到了【位置一】
在後面同步方法裡面又沒有做是否還有餘票的判斷,就會把o號
和-1號
也給賣了。
設想,這樣子如果是在12306,豈不是很混亂,一群人拿著0號,-1號,-2號……
車票一臉懵逼的上了車……