日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【Java多线程】并发时的线程安全:快乐影院示例

發布時間:2024/2/28 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java多线程】并发时的线程安全:快乐影院示例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

快樂影院示例

如果去掉71行的synchronized,會導致線程不安全

結果就是:明明已經沒有票(有人搶先一步),卻又被成功訂走了。圖見文末

下面是正確的代碼:

package cn.hanquan.test;import java.util.ArrayList; import java.util.List;public class HappyCinema {public static void main(String[] args) throws InterruptedException {// 可用位置List<Integer> seats = new ArrayList<Integer>();for (int i = 1; i <= 10; i++)seats.add(i);// 預定位置List<Integer> aWant = new ArrayList<Integer>();aWant.add(1);aWant.add(3);List<Integer> bWant = new ArrayList<Integer>();bWant.add(2);bWant.add(6);List<Integer> cWant = new ArrayList<Integer>();cWant.add(6);cWant.add(7);cWant.add(2);Cinema cm = new Cinema("HappyCinema", seats);Customer a = new Customer(cm, aWant);Customer b = new Customer(cm, bWant);Customer c = new Customer(cm, cWant);a.start();b.start();c.start();Thread.sleep(300);} }class Customer extends Thread {Cinema cinema;List<Integer> want = new ArrayList<Integer>();public Customer(Cinema cinema, List<Integer> want) {this.cinema = cinema;this.want = want;}@Overridepublic void run() {boolean flag = cinema.bookTickets(want);if (flag) {System.out.println("√ 訂票成功 " + Thread.currentThread().getName() + " 你定的 " + want + " 訂后剩余 " + cinema.seats);} else {System.out.println("× 訂票失敗 " + Thread.currentThread().getName() + " 你定的 " + want + " 訂后剩余 " + cinema.seats);}} }class Cinema extends Thread {String name;List<Integer> seats;public Cinema(String name, List<Integer> seats) {System.out.println("歡迎來到:" + name + " 初始化座位:" + seats);this.name = name;this.seats = seats;}public synchronized boolean bookTickets(List<Integer> want) {// System.out.println("空余位置:" + seats);List<Integer> copy = new ArrayList<Integer>();copy.addAll(seats);copy.removeAll(want);if (seats.size() - want.size() == copy.size()) {try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}seats = copy;return true;} else {return false;}} }
運行結果

由于線程由操作系統調度,搶票的結果隨機。

但經過多次試驗,發現大多數情況下,先start()的線程先執行。

偶爾出現下列結果:
大多數時候是下列結果:


附:錯誤的執行結果如果(去掉71行的synchronized)

快樂火車站示例

36行,Thread是可以被強制類型轉換的

package cn.hanquan.test;public class HappyTrain {public static void main(String[] args) throws InterruptedException {Station station = new Station(20, "HappStation");Passenger p1 = new Passenger(station, "猿", 8);Passenger p2 = new Passenger(station, "傻子", 3);Passenger p3 = new Passenger(station, "魚", 11);p1.start();p2.start();p3.start();} }// 作為代理 寫成 extends Thread class Passenger extends Thread {// extends 繼承類int want;// 可以定義線程變量public Passenger(Runnable target, String name, int seats) {super(target, name);// 將父類的構造器延續下來this.want = seats;// 同時自己加入屬性} }class Station implements Runnable {// implements 實現接口int seats;String name;public Station(int seats, String name) {System.out.println("歡迎來到 " + name + " 初始化座位:" + seats);this.seats = seats;this.name = name;}@Overridepublic void run() {Passenger p = (Passenger) Thread.currentThread();// 對應于p1.start(); 強轉回調用start()的類boolean success = this.buyTickets(p.want);if (success) {System.out.println("√ 購票成功 " + Thread.currentThread().getName() + "\t購買:" + p.want + " 成交后剩余:" + seats);} else {System.out.println("× 購票失敗 " + Thread.currentThread().getName() + "\t購買:" + p.want + " 實際剩余:" + seats);}}public synchronized boolean buyTickets(int want) {// System.out.println("剩余位置:" + seats);if (seats > want) {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}seats -= want;return true;} else {return false;}} }

運行結果

總結

以上是生活随笔為你收集整理的【Java多线程】并发时的线程安全:快乐影院示例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。