您好,登錄后才能下訂單哦!
本篇內容主要講解“Java怎么實現站點售票功能”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java怎么實現站點售票功能”吧!
題目要求我們創建5個線程來模擬賣票,當然這其中就包含多線程存在也就是我們要解決的問題,重復賣票和超額賣票。即多個窗口賣出同一張票以及窗口賣出非正數編號的票。
不過這個問題可以先放一下,我們先來創建基礎的線程模型,并在主方法中創建五個線程讓他們跑起來
話不多說,上代碼。
public class Ticket {
public static void main(String[] args) {
for(int i = 1;i <= 5;i++) {
//創建5個線程并啟動他們
//注意一定要使用Thread類創建線程并使用start方法啟動
//而不是直接創建TicketSeller對象調用run方法!!!!!!
new Thread(new TicketSeller(i)).start();
}
}
}
//售票類,實現Runnable接口,可以作為線程執行對象
class TicketSeller implements Runnable{
//該售票窗口編號
private int code;
public TicketSeller(int code) {
this.code = code;
}
@Override
public void run() {
for(int i = 0;i < 5;i++) {
System.out.println(code + "號窗口");
//為了使線程能夠交替執行,打印完成語句讓線程休眠一小會
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
完成了基礎的多線程框架搭建后,我們來為每個線程執行過程中加入賣票的程序
首先要解決的一個問題是:票存在哪里?。毋庸置疑的是由于是多線程并發的售票,因此票這個變量一定是被多個線程所共享的,而不能是每個線程對象自己的屬性。
一個可行的方案是在TicketSellet
類中定義靜態的票計數,這樣所有的線程訪問票的時候訪問的都是同一個票計數變量。
另一個可行方案是使用一個對象管理票,票計數是這個對象的成員,并且讓每個TicketSeller
持有相同的對象。那么多個線程也同樣共享票計數。
當然,可行的方案還有很多,現在我們先來實現第一種,在之后的改進中,我們還會用到第二種。
先來一個沒有加鎖的寫法,看看他的問題
//售票類,實現Runnable接口,可以作為線程執行對象
class TicketSeller implements Runnable{
//票數
private static int tickets = 100;
//該售票窗口編號
private int code;
public TicketSeller(int code) {
this.code = code;
}
@Override
public void run() {
//如果有票就一直賣
while(tickets > 0) {
System.out.println(code + "_____" + tickets--);
//賣過票之后休眠一小會等待其他線程操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Ticket {
public static void main(String[] args) {
for(int i = 1;i <= 5;i++) {
//創建5個線程并啟動他們
//注意一定要使用Thread類創建線程并使用start方法啟動
//而不是直接創建TicketSeller對象調用run方法!!!!!!
new Thread(new TicketSeller(i)).start();
}
}
}
//售票類,實現Runnable接口,可以作為線程執行對象
class TicketSeller implements Runnable{
//票數
private static int tickets = 100;
//同步鎖
private static Object lock = new Object();
//該售票窗口編號
private int code;
public TicketSeller(int code) {
this.code = code;
}
@Override
public void run() {
//如果有票就一直賣
while(tickets > 0) {
synchronized (lock) {
//如果票賣完了則跳出
if(tickets <= 0) {
break;
}
System.out.println(code + "_____" + tickets--);
//賣過票之后休眠一小會等待其他線程操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
在前面我們還提出了另一種方案,就是使用一個對象管理票的售賣。這種方案就不展開啰嗦了,直接上代碼:
public class Ticket {
public static void main(String[] args) {
//創建一個票管理對象,票數為100
TicketSet ts = new TicketSet(100);
//創建5個線程,使用同一個票管理對象
for(int i = 1;i <= 5;i++) {
new Thread(new TicketSeller(ts, i)).start();
}
}
}
//票管理類
class TicketSet{
//票數
private int tickets;
public TicketSet(int tickets) {
this.tickets = tickets;
}
private boolean hasTicket() {
return tickets > 0;
}
//售票方法,使用同步鎖,每次只能有一個線程訪問該方法
//返回結果為是否賣出去票
synchronized public boolean sellTicket(int code) {
if(hasTicket()) {
System.out.println(code + "_____" + tickets--);
return true;
}else {
return false;
}
}
}
//售票類
class TicketSeller implements Runnable{
//票管理對象
private TicketSet ts;
private int code;
public TicketSeller(TicketSet ts,int code) {
this.ts = ts;
this.code = code;
}
@Override
public void run() {
//嘗試調用票管理的售票方法,售票成功后休眠一小會
while(ts.sellTicket(code)){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
到此,相信大家對“Java怎么實現站點售票功能”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。