欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java多線程之火車售票系統(tǒng)模擬實例

 更新時間:2017年06月26日 08:55:14   投稿:jingxian  
下面小編就為大家?guī)硪黄猨ava多線程之火車售票系統(tǒng)模擬實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1.前言

為了學習多線程共享與通信,我們模擬一個火車售票系統(tǒng),假設有10張火車票,三個窗口(也就是三個線程)同時進行售票。

2.非同步代碼

package com.tl.skyLine.thread; 
 
/** 
 * Created by tl on 17/3/6. 
 */ 
public class SellTicket { 
 
  public static void main(String[] args) { 
    TicketWindow tw = new TicketWindow(); 
    Thread t1 = new Thread(tw, "一號窗口"); 
    Thread t2 = new Thread(tw, "二號窗口"); 
    Thread t3 = new Thread(tw, "三號窗口"); 
    t1.start(); 
    t2.start(); 
    t3.start(); 
  } 
} 
 
class TicketWindow implements Runnable { 
  private int tickets = 10; 
 
  @Override 
  public void run() { 
    while (true) { 
      if (tickets > 0) { 
        System.out.println("還剩余票:" + tickets + "張"); 
        tickets--; 
        System.out.println(Thread.currentThread().getName() + "賣出一張火車票,還剩" + tickets + "張"); 
      } else { 
        System.out.println("余票不足,暫停出售!"); 
//        wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用 
        try { 
          Thread.sleep(1000 * 60 * 5); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    } 
  } 
} 

打印結果:

還剩余票:10張 
還剩余票:10張 
還剩余票:10張 
二號窗口賣出一張火車票,還剩7張 
還剩余票:7張 
三號窗口賣出一張火車票,還剩8張 
一號窗口賣出一張火車票,還剩9張 
還剩余票:6張 
還剩余票:6張 
二號窗口賣出一張火車票,還剩6張 
還剩余票:4張 
三號窗口賣出一張火車票,還剩4張 
還剩余票:3張 
一號窗口賣出一張火車票,還剩5張 
三號窗口賣出一張火車票,還剩2張 
還剩余票:2張 
三號窗口賣出一張火車票,還剩1張 
還剩余票:1張 
三號窗口賣出一張火車票,還剩0張 
余票不足,暫停出售! 
二號窗口賣出一張火車票,還剩3張 
余票不足,暫停出售! 
還剩余票:2張 
一號窗口賣出一張火車票,還剩-1張 
余票不足,暫停出售! 

上面結果,可以清楚地看到,由于三個線程可以同時訪問一個任務,也就是售票任務,會出現(xiàn)火車票還剩-1張這種不合實際的問題,之所以出現(xiàn)是因為假設在某一瞬間,tickets為1時,tickets > 0為true,A線程運行到tickets--這一行代碼,此時還沒有減去1,同時另外一個線程B剛好運行到tickets > 0這一行代碼,判斷成功,開始執(zhí)行賣票,此時A線程減去一張票,tickets=0,然后B線程又減去一張,則剩-1張。所以此時需要用到同步鎖synchronized。保證某一時刻只能有一個線程執(zhí)行售票功能。

3.同步代碼

package com.tl.skyLine.thread; 
 
/** 
 * Created by tl on 17/3/6. 
 */ 
public class SellTicket { 
 
  public static void main(String[] args) { 
    TicketWindow tw = new TicketWindow(); 
    Thread t1 = new Thread(tw, "一號窗口"); 
    Thread t2 = new Thread(tw, "二號窗口"); 
    Thread t3 = new Thread(tw, "三號窗口"); 
    t1.start(); 
    t2.start(); 
    t3.start(); 
  } 
} 
 
class TicketWindow implements Runnable { 
  private int tickets = 10; 
 
  @Override 
  public synchronized void run() { 
    while (true) { 
      if (tickets > 0) { 
        System.out.println(Thread.currentThread().getName() + "準備出票,還剩余票:" + tickets + "張"); 
        tickets--; 
        System.out.println(Thread.currentThread().getName() + "賣出一張火車票,還剩" + tickets + "張"); 
      } else { 
        System.out.println("余票不足,暫停出售!"); 
//        wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用 
        try { 
          Thread.sleep(1000 * 60 * 5); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 
    } 
  } 
} 

等同于:

class TicketWindow implements Runnable {                                           
  private int tickets = 10;                                                 
                                                               
  @Override                                                         
  public void run() {                                                    
    while (true) {                                                    
      synchronized (this) {                                               
        if (tickets > 0) {                                              
          System.out.println(Thread.currentThread().getName() + "準備出票,還剩余票:" + tickets + "張");           
          tickets--;                                                
          System.out.println(Thread.currentThread().getName() + "賣出一張火車票,還剩" + tickets + "張");           
        } else {                                                   
          System.out.println("余票不足,暫停出售!");                                     
//        wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用                          
          try {                                                   
            Thread.sleep(1000 * 60 * 5);                                     
          } catch (InterruptedException e) {                                    
            e.printStackTrace();                                         
          }                                                     
        }                                                       
      }                                                         
    }                                                           
  }                                                             
}              

結果:

一號窗口準備出票,還剩余票:10張 
一號窗口賣出一張火車票,還剩9張 
一號窗口準備出票,還剩余票:9張 
一號窗口賣出一張火車票,還剩8張 
一號窗口準備出票,還剩余票:8張 
一號窗口賣出一張火車票,還剩7張 
一號窗口準備出票,還剩余票:7張 
一號窗口賣出一張火車票,還剩6張 
一號窗口準備出票,還剩余票:6張 
一號窗口賣出一張火車票,還剩5張 
一號窗口準備出票,還剩余票:5張 
一號窗口賣出一張火車票,還剩4張 
一號窗口準備出票,還剩余票:4張 
一號窗口賣出一張火車票,還剩3張 
一號窗口準備出票,還剩余票:3張 
一號窗口賣出一張火車票,還剩2張 
一號窗口準備出票,還剩余票:2張 
一號窗口賣出一張火車票,還剩1張 
一號窗口準備出票,還剩余票:1張 
一號窗口賣出一張火車票,還剩0張 
余票不足,暫停出售! 

synchronized:

synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:

1. 修飾一個代碼塊,被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象;

2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象;

3. 修改一個靜態(tài)的方法,其作用的范圍是整個靜態(tài)方法,作用的對象是這個類的所有對象;

4. 修改一個類,其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象。

以上這篇java多線程之火車售票系統(tǒng)模擬實例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 本地MinIO存儲服務Java遠程調用上傳文件的操作過程

    本地MinIO存儲服務Java遠程調用上傳文件的操作過程

    MinIO是一款高性能、分布式的對象存儲系統(tǒng),它可以100%的運行在標準硬件上,即X86等低成本機器也能夠很好的運行MinIO,這篇文章主要介紹了本地MinIO存儲服務Java遠程調用上傳文件的操作過程,需要的朋友可以參考下
    2023-11-11
  • SpringBoot如何添加WebSocket的方法示例

    SpringBoot如何添加WebSocket的方法示例

    這篇文章主要介紹了SpringBoot如何添加WebSocket的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 詳解Java編程的Observer觀察者設計模式

    詳解Java編程的Observer觀察者設計模式

    這篇文章主要介紹了Java編程的Observer觀察者設計模式,觀察者模式定義了一個一對多的依賴關系,讓一個或多個觀察者對象監(jiān)察一個主題對象,需要的朋友可以參考下
    2016-01-01
  • Java對象轉JSON時動態(tài)的增刪改查屬性詳解

    Java對象轉JSON時動態(tài)的增刪改查屬性詳解

    這篇文章主要介紹了Java對象轉JSON時如何動態(tài)的增刪改查屬性的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • SpringBoot靜態(tài)資源CSS等修改后再運行無效的解決

    SpringBoot靜態(tài)資源CSS等修改后再運行無效的解決

    這篇文章主要介紹了SpringBoot靜態(tài)資源CSS等修改后再運行無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Mybatis-Plus處理Mysql?Json類型字段的詳細教程

    Mybatis-Plus處理Mysql?Json類型字段的詳細教程

    這篇文章主要給大家介紹了關于Mybatis-Plus處理Mysql?Json類型字段的詳細教程,Mybatis-Plus可以很方便地處理JSON字段,在實體類中可以使用@JSONField注解來標記JSON字段,同時在mapper.xml中使用json函數(shù)來操作JSON字段,需要的朋友可以參考下
    2024-01-01
  • Java中繼承、多態(tài)、重載和重寫介紹

    Java中繼承、多態(tài)、重載和重寫介紹

    這篇文章主要介紹了Java中繼承、多態(tài)、重載和重寫介紹,需要的朋友可以參考下
    2014-07-07
  • Java實現(xiàn)將PDF轉為PDF/A

    Java實現(xiàn)將PDF轉為PDF/A

    通過將PDF格式轉換為PDF/A格式,可保護文檔布局、格式、字體、大小等不受更改,從而實現(xiàn)文檔安全保護的目的,同時又能保證文檔可讀、可訪問。本文將為大家介紹如何實現(xiàn)這一轉換,需要的可以參考一下
    2022-01-01
  • spring boot(三)之Spring Boot中Redis的使用

    spring boot(三)之Spring Boot中Redis的使用

    這篇文章主要介紹了spring boot(三)之Spring Boot中Redis的使用,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-05-05
  • SpringBoot整合WebSocket實現(xiàn)后端向前端發(fā)送消息的實例代碼

    SpringBoot整合WebSocket實現(xiàn)后端向前端發(fā)送消息的實例代碼

    WebSocket使得客戶端和服務器之間的數(shù)據交換變得更加簡單,允許服務端主動向客戶端推送數(shù)據,下面這篇文章主要給大家介紹了關于SpringBoot整合WebSocket實現(xiàn)后端向前端發(fā)送消息的相關資料,需要的朋友可以參考下
    2023-03-03

最新評論