JavaSE-20.2.2【线程同步:同步代码块、同步方法解决数据安全问题(卖票案例问题解决)】
1 package day11.lesson2; 2 3 /* 4 2.3 同步代码块解决数据安全问题(卖票案例问题解决) 5 6 卖票案例为啥会出现问题?(多线程程序出现安全问题的标准条件) 7 是多线程环境 8 有共享数据 9 有多条语句操作共享数据 10 11 如何解决多线程安全问题呢? 12 基本思想:让程序没有安全问题的环境,即至少破坏掉上述其中一个条件 13 14 怎么实现呢? 15 把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可 16 Java提供了同步代码块的方式来解决 17 18 同步代码块格式: 19 synchronized(任意对象) { 20 多条语句操作共享数据的代码 21 } 22 synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁 23 24 同步的好处和弊端 25 好处:解决了多线程的数据安全问题 26 弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率 27 28 */ 29 public class SellTicket2 implements Runnable{ 30 31 private int tickets = 100; 32 private Object obj = new Object(); 33 34 @Override 35 public void run() { 36 while (true){ 37 synchronized (obj){ 38 if(tickets > 0){ 39 try { 40 Thread.sleep(100); 41 } catch (InterruptedException e) { 42 e.printStackTrace(); 43 } 44 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); 45 tickets--; 46 } 47 } 48 } 49 } 50 } 51 52 class SellTicketDemo2{ 53 public static void main(String[] args) { 54 SellTicket2 st = new SellTicket2(); 55 56 Thread t1 = new Thread(st, "窗口1"); 57 Thread t2 = new Thread(st, "窗口2"); 58 Thread t3 = new Thread(st, "窗口3"); 59 60 t1.start(); 61 t2.start(); 62 t3.start(); 63 } 64 }
1 package day11.lesson2; 2 3 /* 4 2.4 同步方法解决数据安全问题 5 6 同步方法 7 同步方法:就是把synchronized关键字加到方法上 8 修饰符 synchronized 返回值类型 方法名(方法参数) { 9 方法体; 10 } 11 同步方法的锁对象是什么呢? 12 this 13 14 静态同步方法 15 同步静态方法:就是把synchronized关键字加到静态方法上 16 修饰符 static synchronized 返回值类型 方法名(方法参数) { 17 方法体; 18 } 19 同步静态方法的锁对象是什么呢? 20 类名.class 21 */ 22 public class SellTicket3 implements Runnable{ 23 24 // private int tickets = 100; 25 private static int tickets = 100; 26 private Object obj = new Object(); 27 private int x = 0; 28 29 @Override 30 public void run() { 31 while (true){ 32 if(x % 2 == 0){ 33 // synchronized (obj){ 34 // synchronized (this){ 35 synchronized (SellTicket.class){ 36 if(tickets > 0){ 37 try { 38 Thread.sleep(100); 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } 42 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); 43 tickets--; 44 } 45 } 46 }else { 47 /*synchronized (obj){ 48 if(tickets > 0){ 49 try { 50 Thread.sleep(100); 51 } catch (InterruptedException e) { 52 e.printStackTrace(); 53 } 54 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); 55 tickets--; 56 } 57 }*/ 58 sellTickets(); 59 } 60 x++; 61 } 62 } 63 64 /*private void sellTickets() { 65 synchronized (obj){ 66 if(tickets > 0){ 67 try { 68 Thread.sleep(100); 69 } catch (InterruptedException e) { 70 e.printStackTrace(); 71 } 72 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); 73 tickets--; 74 } 75 } 76 }*/ 77 78 private static synchronized void sellTickets() { //静态同步方法 79 if(tickets > 0){ 80 try { 81 Thread.sleep(100); 82 } catch (InterruptedException e) { 83 e.printStackTrace(); 84 } 85 System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); 86 tickets--; 87 } 88 } 89 90 } 91 92 93 class SellTicketDemo3{ 94 public static void main(String[] args) { 95 SellTicket3 st = new SellTicket3(); 96 97 Thread t1 = new Thread(st, "窗口1"); 98 Thread t2 = new Thread(st, "窗口2"); 99 Thread t3 = new Thread(st, "窗口3"); 100 101 t1.start(); 102 t2.start(); 103 t3.start(); 104 } 105 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!