JAVA併發編程下保證車票出售線程安全之synchronized鎖

在併發編程場景下如何保證車票或者商品出售業務是線程安全的?

首先我們就會想到加鎖,來保證出售業務線程安全。但是加鎖勢必會帶來性能上的瓶頸。那麼我們就會思考,還有沒有其它的方式避免加鎖來實現同樣的效果呢?

這裏我們帶着這個問題,先採用常見的加鎖方式來實現。

package com.sync.ticket;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

/**
 * 12306有N張代售車票或者庫存有N件商品
 *
 * @author 小輝GE/小輝哥
 * <p>
 * 2019年8月11日 下午19:40:00
 */

public class TicketSellerSync {

    static List<String> tickets = new ArrayList<>();
    //static List<String> tickets = new Vector<>();

    static {
        for (int i = 0; i < 1000; i++) tickets.add("車票/商品編號:" + i);
    }

    public static void main(String[] args) {
		/*for (int i = 0; i < 10; i++) {
			new Thread(() -> {
				while (tickets.size() > 0) {
					try {
						TimeUnit.MILLISECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(tickets.remove(0) + "已賣出");
				}
			}).start();
		}*/

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                while (true) {
                    synchronized (tickets) {
                        if (tickets.size() <= 0) break;
                        try {
                            TimeUnit.MILLISECONDS.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(tickets.remove(0) + "已賣出");
                    }
                }
            }).start();
        }
    }
}

測試輸出結果如下(輸出結果比較多,我們只截取部分):

結果分析:

我們可以看出加鎖是肯定能保證線程安全,保證車票或者商品出售業務不會重複,或者超出範圍。那麼,我們只能加鎖來實現嗎,有沒有更高效的不用加鎖的方式,其實是有的,我們可以用線程安全的同步隊列來實現,但是一定要保證操作方法是原子性的。下一篇我們會用ConcurrentLinkedQueue的方式來實現。

以上代碼僅供參考,如有不當之處,歡迎指出!!!

更多幹貨,歡迎大家關注和聯繫我。期待和大家一起更好的交流、探討技術!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章