多執行緒實現買票問題
阿新 • • 發佈:2022-01-07
實現Runnable介面的方式實現四個執行緒賣100張火車票的問題
點選檢視程式碼
public class TestTicket { public static void main(String[] args) { // 啟動四個執行緒賣票。 TicketThread tt = new TicketThread();//一個執行緒物件 new Thread(tt).start();//啟動四個執行緒,操作TicketThread類中的 tickets成員變數 new Thread(tt).start(); new Thread(tt).start(); new Thread(tt).start(); } } class TicketThread implements Runnable { // 100張票。 private Integer tickets = 100;//爭用資源.. @Override public void run() { while (tickets > 0) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (this) {//臨界區,當某個執行緒進入臨界區後,其它執行緒必需等該執行緒執行完畢後,才有機會進入到該程式碼塊中 if(tickets>0) {//此處判斷是為了避免出現負數的情況 System.out.println(Thread.currentThread() + " is saling ticket " + tickets); tickets--; } } } } }
點選檢視程式碼
public class TestTicket2 { public static void main(String[] args) { // 啟動四個執行緒賣票。 TicketThread2 t1 = new TicketThread2(); t1.start(); TicketThread2 t2 = new TicketThread2(); t2.start(); TicketThread2 t3 = new TicketThread2(); t3.start(); TicketThread2 t4 = new TicketThread2(); t4.start(); } } class TicketThread2 extends Thread { private static Integer tickets = 100;//靜態的變數隸屬於類,不屬於物件,多個物件共享的。 @Override public void run() { while (tickets > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } /* this代表當前物件,我們建立了四個TicketThread2類的物件,this分別程式碼這四個物件; 相當於有四個物件分別上鎖和開鎖(廁所有四個門),所以不可取; 所以我們得為共享靜態變數所屬於的類上鎖,即:TicketThread類上鎖。 */ synchronized (TicketThread2.class) { if(tickets>0) {//此片判斷是為了避免出現負數的情況 System.out.println(Thread.currentThread() + "賣出了第" + tickets + "張票"); tickets--; } } } } }
點選檢視程式碼
public class TestTicket3 { public static void main(String[] args) { Ticket ticket = new Ticket(); ticket.tickets = 150; // 啟動四個執行緒賣票。 TicketThread3 t1 = new TicketThread3(ticket); t1.start(); TicketThread3 t2 = new TicketThread3(ticket); t2.start(); TicketThread3 t3 = new TicketThread3(ticket); t3.start(); TicketThread3 t4 = new TicketThread3(ticket); t4.start(); } } //在Thread類中用成員代表火車票或定義靜態變數都不合適的情況下,我們可以把火車票單獨拿出來,然後傳入到執行緒類中 class Ticket{//代表火車票 int tickets=100; } class TicketThread3 extends Thread { Ticket ticket; public TicketThread3(Ticket ticket){ this.ticket = ticket; } @Override public void run() { while (ticket.tickets > 0) { synchronized (ticket) { if(ticket.tickets>0) {//此片判斷是為了避免出現負數的情況 System.out.println(Thread.currentThread() + " 已賣 " + ticket.tickets); ticket.tickets--; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } }