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 }
复制代码

 

posted @   yub4by  阅读(84)  评论(0编辑  收藏  举报
编辑推荐:
· 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 让容器管理更轻松!
点击右上角即可分享
微信分享提示