1. 程式人生 > >Java多執行緒實現視窗售票的功能

Java多執行緒實現視窗售票的功能

在這個程式中我們一共售賣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號……車票一臉懵逼的上了車……