教你用三種方式模擬兩個(gè)線程搶票
共 9682字,需瀏覽 20分鐘
·
2024-06-25 09:19
往期熱門文章:
1、MySQL中varchar(50)和varchar(500)區(qū)別是什么?
使用 Synchronized 來確保一次只有一個(gè)線程可以訪問票資源。
使用 ReentrantLock 來實(shí)現(xiàn)線程間的協(xié)調(diào)。
使用 Semaphore 來限制同時(shí)訪問票的線程數(shù)量。
static class TicketSystemBySynchronized {private int tickets = 100;public void sellTicket() {while (tickets > 0) { //還有票時(shí)進(jìn)行循環(huán)synchronized (this) {try {if (tickets > 0)System.out.println(Thread.currentThread().getName()+ "賣出一張票,剩余票數(shù):" + --tickets);Thread.sleep(200); //模擬售票} catch (InterruptedException e) {e.printStackTrace();}}}}}
static class TicketSystemByReentrantLock {private int tickets = 100;private final ReentrantLock lock = new ReentrantLock(); //定義鎖public void sellTicket() {while (tickets > 0) {lock.lock(); //上鎖try {Thread.sleep(200); //模擬售票if (tickets > 0)System.out.println(Thread.currentThread().getName()+ "賣出一張票,剩余票數(shù):" + --tickets);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock(); //解鎖}}}}
static class TicketSystemBySemaphore {private final Semaphore semaphore;public TicketSystemBySemaphore() {this.semaphore = new Semaphore(100); //總共100張票}public void sellTicket() {int i = semaphore.availablePermits(); //返回此信號(hào)量中當(dāng)前可用的許可證數(shù)while (i > 0) {try {Thread.sleep(200);semaphore.acquire(); // 獲取信號(hào)量,如果信號(hào)量為0,線程將阻塞等待System.out.println(Thread.currentThread().getName() + "賣出一張票,剩余票數(shù):" + --i);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {semaphore.release(); // 釋放信號(hào)量,允許其他線程獲取信號(hào)量}}}}
public interface TicketSystem {void sellTicket();}
static class CodeSandboxFactory {static TicketSystem newInstance(String type) {switch (type) {case "Synchronized":return new TicketSystemBySynchronized();case "ReentrantLock":return new TicketSystemByReentrantLock();case "Semaphore":default:return new TicketSystemBySemaphore();}}}
如果type參數(shù)的值為"Synchronized",則返回一個(gè)新的 TicketSystemBySynchronized對(duì)象;
如果type參數(shù)的值為"ReentrantLock",則返回一個(gè)新的 TicketSystemByReentrantLock 對(duì)象;
如果type參數(shù)的值為"Semaphore",則返回一個(gè)新的 TicketSystemBySemaphore對(duì)象;
如果type參數(shù)的值不是以上三種之一,則默認(rèn)返回一個(gè)新的TicketSystemBySemaphore 對(duì)象。
public class ThreadsGrabTickets {public static void main(String[] args) {TicketSystem system = CodeSandboxFactory.newInstance("Synchronized");// TicketSystem system =// CodeSandboxFactory.newInstance("ReentrantLock"); TicketSystem// system = CodeSandboxFactory.newInstance("Semaphore");new Thread(system::sellTicket, "線程1").start();new Thread(system::sellTicket, "線程2").start();}static class CodeSandboxFactory {static TicketSystem newInstance(String type) {switch (type) {case "Synchronized":return new TicketSystemBySynchronized();case "ReentrantLock":return new TicketSystemByReentrantLock();case "Semaphore":default:return new TicketSystemBySemaphore();}}}static class TicketSystemBySynchronized implements TicketSystem {private int tickets = 100;public void sellTicket() {while (tickets > 0) {synchronized (this) {try {if (tickets > 0)System.out.println(Thread.currentThread().getName()+ "賣出一張票,剩余票數(shù):" + --tickets);Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}}}}}static class TicketSystemByReentrantLock implements TicketSystem {private int tickets = 100;private final ReentrantLock lock = new ReentrantLock(); //定義鎖public void sellTicket() {while (tickets > 0) {lock.lock(); //上鎖try {Thread.sleep(200); //模擬售票if (tickets > 0)System.out.println(Thread.currentThread().getName()+ "賣出一張票,剩余票數(shù):" + --tickets);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock(); //解鎖}}}}static class TicketSystemBySemaphore implements TicketSystem {private final Semaphore semaphore;public TicketSystemBySemaphore() {this.semaphore = new Semaphore(100); //總共100張票}public void sellTicket() {int i = semaphore.availablePermits(); //返回此信號(hào)量中當(dāng)前可用的許可證數(shù)while (i > 0) {try {Thread.sleep(200);semaphore.acquire(); // 獲取信號(hào)量,如果信號(hào)量為0,線程將阻塞等待System.out.println(Thread.currentThread().getName()+ "賣出一張票,剩余票數(shù):" + --i);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {semaphore.release(); // 釋放信號(hào)量,允許其他線程獲取信號(hào)量}}}}}
轉(zhuǎn)自:綠皮龜,
鏈接:blog.csdn.net/kologin/article/details/135953580
往期熱門文章:
1、聽說你還在用Xshell? 2、驚艷到我的 10個(gè) MySQL高級(jí)查詢技巧! 3、我有點(diǎn)想用JDK17了 4、解放大腦:ChatGPT + PlantUML = 不用畫圖了 5、高逼格的SQL寫法:行行比較 6、限流算法哪家強(qiáng)?時(shí)間窗口,令牌桶與漏桶算法對(duì)比 7、每天都提交代碼,那你知道.git目錄內(nèi)部的秘密嗎? 8、我患上了空指針后遺癥 9、這10個(gè)小技巧讓你減少80%的Bug! 10、升級(jí) JDK17 一個(gè)不可拒絕的理由
評(píng)論
圖片
表情
