1 package multithread.test;
2
3 import com.sun.org.apache.bcel.internal.generic.NEW;
4
5 /*
6 * 卖票
7 */
8
9
10 /*
11 * 线程安全问题产生的原因:
12 * 1,多个线程在操作共享的数据。
13 * 2,操作共享数据的线程代码有多条。
14 *
15 * 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。
16 * 就会导致线程安全问题的产生。
17 *
18 *
19 * 解决思路:
20 * 就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候
21 * 其他线程是不可以参与运算的。
22 * 必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
23 *
24 *
25 * 在java中,用同步代码块就可以解决这个问题。
26 *
27 * 同步代码块的格式:
28 * synchronize(对象){
29 * 需要被同步的代码块
30 * }
31 * 同步代码块的好处:解决了线程的安全问题。
32 *
33 *
34 * 同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。
35 *
36 * 同步的前提:必须有多个线程并使用同一个锁。
37 *
38 *
39 *
40 */
41
42
43 class Ticket implements Runnable {//extends Thread {
44 private /*static*/ int num = 100;//静态是可以的,根据实际看,有可能是这个线程负责这种100张,另一个线程时另一种票100张
45 Object obj = new Object();
46 public void run() /*throws 不处理就抛,但是实现接口覆盖的方法,接口没有声明过异常,只能catch不能声明*/{
47 // Object obj = new Object();//每个线程开启都会创建一个对象,就会有不同锁,会出错
48 while(true) {
49 synchronized (obj/*对象锁或者叫同步锁*/){
50 if (num>0) {
51 // try {
52 // Thread.sleep(10);//sleep方法有个抛出
53 // } catch (InterruptedException e) {
54 // // TODO: handle exception
55 // }
56 // //
57 System.out.println(Thread.currentThread().getName()+"....sale...."+ num--);
58 }
59 }
60
61
62 }
63 }
64 }
65
66 public class TicketDemo {
67
68 public static void main(String[] args) {
69 // TODO Auto-generated method stub
70
71 Ticket t = new Ticket();//创建一个线程任务对象。
72
73
74 Thread t1 = new Thread(t);
75 Thread t2 = new Thread(t);
76 Thread t3 = new Thread(t);
77 Thread t4 = new Thread(t);
78
79 t1.start();
80 t2.start();
81 t3.start();
82 t4.start();
83 /*
84 Ticket t1 = new Ticket();
85 Ticket t2 = new Ticket();
86 Ticket t3 = new Ticket();
87 Ticket t4 = new Ticket();
88 //只有100张,卖了400张,为什么?
89 t1.start();
90 // t1.start();IllegalThreadStateException-无效线程状态异常是 runtime异常
91 // t1.start();
92 // t1.start();
93
94 t2.start();
95 t3.start();
96 t4.start();
97 */
98
99
100 }
101 //cmd 打印完1在前面 比如43打印在后面, cmd是应用程序,虚拟机也是一个应用程序,cpu也是在这两个中切换造成的
102 }