1 /*
2
3 线程安全:如果有多个线程在同时运行,而这些线程可能会同时运行这段代码,程序每次运行结果和单线程运行的结果是一样的,
4
5 而且其他的变量的值也和预期的是一样的,就是线程安全的
6
7 线程安全是由全局变量及静态变量引起的,若每个线程中对全局变量、静态变量只有读操作,而无写操作,这个全局变量是线程安全的;
8
9 若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全
10
11 */
12
13 public class ThreadDemo{
14
15 public static void main(String[] args){
16
17 //创建票对象
18
19 Ticket t = new Ticket();
20
21 //创建3个窗口
22
23 Thread t1 = new Thread(t , "窗口1");
24
25 Thread t2 = new Thhread(t , "窗口2");
26
27 Thread t3 = new Thhread(t , "窗口3");
28 t1.start();
29
30 t2.start();
31
32 t3.start();
33
34 }
35
36 }
37
38 public class Ticket implements Runnable{
39
40 int ticket = 10;
41
42 public void run(){
43
44 //模拟卖票
45
46 while(true){
47
48 if(ticket > 0){
49
50 //模拟选坐的操作
51
52 try{
53
54 Thread.sleep(2000);
55
56 }catch(Exception e){
57
58 e.printStackTrace();
59
60 }
61
62 System.out.println("正在售票:" + ticket--);
63
64 }
65
66 }
67
68 }
69
70 }
71
72 /*
73
74 线程同步:Java中提供了线程同步机制,能够解决线程安全问题
75
76 方式:
77
78 1、同步代码块
79
80 synchronized(锁对象){可能产生线程安全问题的代码}
81
82 锁对象可以是任意对象,但多个线程时,要使用同一个锁对象才能够保证线程安全
83
84 2、同步方法
85
86 public synchronized void method(){可能产生线程安全问题的代码}
87 锁对象是this
88
89 3、静态同步方法
90
91 public static synchronized void method(){可能产生线程安全问题的代码}
92 锁对象是类名.class
93
94 */
95
96 public class Ticket implements Runnable{
97
98 int ticket = 10;
99
100 //定义锁对象
101
102 Object lock = new Object();
103
104 public void run(){
105
106 //模拟卖票
107
108 while(true){
109
110 //同步代码块
111
112 synchronized(lock){
113 if(ticket > 0){
114
115 //模拟选坐的操作
116
117 try{
118
119 Thread.sleep(2000);
120
121 }catch(Exception e){
122
123 e.printStackTrace();
124
125 }
126
127 System.out.println("正在售票:" + ticket--);
128
129 }
130
131 }
132
133 }
134
135 }
136
137 }
138
139
140
141 public class Ticket implements Runnable{
142
143 int ticket = 10;
144
145 //定义锁对象
146
147 Object lock = new Object();
148
149 public void run(){
150
151 //模拟卖票
152
153 while(true){
154
155 //同步方法
156
157 method();
158
159 }
160
161 }
162
163 public synchronized void method(){
164
165 if(ticket > 0){
166
167 //模拟选坐的操作
168
169 try{
170
171 Thread.sleep(2000);
172
173 }catch(Exception e){
174
175 e.printStackTrace();
176
177 }
178
179 System.out.println("正在售票:" + ticket--);
180
181 }
182
183 }
184
185 }
186
187 /*
188
189 死锁:当线程任务中出现了多个同步(多个锁时,如果同步中嵌套了其他同步,这时容易引发一种现象:程序出现无限等待,这种现象称为死锁)
190
191 synchronized(A锁){
192
193 synchronized(B锁){
194
195 }
196 }
197
198 */
199
200 //定义锁对象类
201
202 public class MyLock{
203
204 public static final Object locka = new Object();
205
206 public static final Object lockb = new Object();
207 }
208
209 public class ThreadTask implements Runnable{
210
211 int x = new Random().nextInt(1);
212
213 //指定线程要执行的任务代码
214
215 public void run(){
216
217 while(true){
218
219 if(x % 2 == 0){
220
221 synchronized(MyLock.locka){
222
223 System.out.println("if-locka");
224
225 synchronized(MyLock.lockb){
226
227 System.out.println("if-lockb");
228
229 }
230 }
231 }else{
232
233 synchronized(MyLock.lockb){
234
235 System.out.println("else-lockb");
236
237 synchronized(MyLock.locka){
238
239 System.out.println("else-locka");
240 }
241 }
242 }
243
244 }
245
246 }
247
248 }
249
250 /*
251
252 Lock类:
253
254 void lock():获取锁
255
256 void unlock():释放锁
257
258 */
259
260 public class Ticket implements Runnable{
261
262 int ticket = 10;
263
264 //定义Lock锁对象
265
266 Lock lock = new ReentrantLoak();
267
268 public void run(){
269
270 //模拟卖票
271
272 while(true){
273
274 lock.lock();
275
276 if(ticket > 0){
277
278 //模拟选坐的操作
279
280 try{
281
282 Thread.sleep(2000);
283
284 }catch(Exception e){
285
286 e.printStackTrace();
287
288 }
289
290 System.out.println("正在售票:" + ticket--);
291
292 }
293
294 lock.unlock();
295
296 }
297
298 }
299
300 }
301
302 }
303
304 /*
305
306 等待唤醒机制:让线程池中的线程具备执行功能
307
308 void wait():等待,将正在执行的线程释放其执行资格和执行权,并存储到线程池中
309
310 void notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且时任意的
311
312 void notifyAll():唤醒全部,可以将线程池中的所有wait()线程唤醒
313
314 */