教你用三种方式模拟两个线程抢票
共 9682字,需浏览 20分钟
·
2024-06-25 09:19
往期热门文章:
使用 Synchronized 来确保一次只有一个线程可以访问票资源。
使用 ReentrantLock 来实现线程间的协调。
使用 Semaphore 来限制同时访问票的线程数量。
static class TicketSystemBySynchronized {private int tickets = 100;public void sellTicket() {while (tickets > 0) { //还有票时进行循环synchronized (this) {try {if (tickets > 0)System.out.println(Thread.currentThread().getName()+ "卖出一张票,剩余票数:" + --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()+ "卖出一张票,剩余票数:" + --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(); //返回此信号量中当前可用的许可证数while (i > 0) {try {Thread.sleep(200);semaphore.acquire(); // 获取信号量,如果信号量为0,线程将阻塞等待System.out.println(Thread.currentThread().getName() + "卖出一张票,剩余票数:" + --i);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {semaphore.release(); // 释放信号量,允许其他线程获取信号量}}}}
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参数的值为"Synchronized",则返回一个新的 TicketSystemBySynchronized对象;
如果type参数的值为"ReentrantLock",则返回一个新的 TicketSystemByReentrantLock 对象;
如果type参数的值为"Semaphore",则返回一个新的 TicketSystemBySemaphore对象;
如果type参数的值不是以上三种之一,则默认返回一个新的TicketSystemBySemaphore 对象。
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()+ "卖出一张票,剩余票数:" + --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()+ "卖出一张票,剩余票数:" + --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(); //返回此信号量中当前可用的许可证数while (i > 0) {try {Thread.sleep(200);semaphore.acquire(); // 获取信号量,如果信号量为0,线程将阻塞等待System.out.println(Thread.currentThread().getName()+ "卖出一张票,剩余票数:" + --i);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {semaphore.release(); // 释放信号量,允许其他线程获取信号量}}}}}
转自:绿皮龟,
链接:blog.csdn.net/kologin/article/details/135953580
往期热门文章:
1、听说你还在用Xshell? 2、惊艳到我的 10个 MySQL高级查询技巧! 3、我有点想用JDK17了 4、解放大脑:ChatGPT + PlantUML = 不用画图了 5、高逼格的SQL写法:行行比较 6、限流算法哪家强?时间窗口,令牌桶与漏桶算法对比 7、每天都提交代码,那你知道.git目录内部的秘密吗? 8、我患上了空指针后遗症 9、这10个小技巧让你减少80%的Bug! 10、升级 JDK17 一个不可拒绝的理由
评论
