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 }