@@ -212,8 +212,83 @@ synchronized(Object){
212
212
213
213
## volatile 共享内存
214
214
215
+ 因为 Java 其实是采用共享内存的方式进行线程通信的,所以可以采用以下方式用主线程关闭 A 线程:
216
+
217
+ ``` java
218
+ public class Volatile implements Runnable {
219
+
220
+ private static volatile boolean flag = true ;
221
+
222
+ @Override
223
+ public void run () {
224
+ while (flag){
225
+ System . out. println(Thread . currentThread(). getName() + " 正在运行。。。" );
226
+ }
227
+ System . out. println(Thread . currentThread(). getName() + " 执行完毕" );
228
+ }
229
+
230
+ public static void main (String [] args ) throws InterruptedException {
231
+ Volatile aVolatile = new Volatile ();
232
+ new Thread (aVolatile," thread A" ). start();
233
+
234
+
235
+ System . out. println(" main 线程正在运行" ) ;
236
+
237
+ TimeUnit . MILLISECONDS. sleep(100 ) ;
238
+
239
+ aVolatile. stopThread();
240
+
241
+ }
242
+
243
+ private void stopThread (){
244
+ flag = false ;
245
+ }
246
+ }
247
+ ```
248
+
249
+ 这里的 flag 存放于主内存中,所以主线程和线程 A 都可以看到。
250
+
251
+ flag 采用 volatile 修饰主要是为了内存可见性,具体内容可以查看[ 这里] ( http://crossoverjie.top/2018/03/09/volatile/ ) 。
252
+
253
+
215
254
## CountDownLatch 并发工具
216
255
256
+ CountDownLatch 可以实现 join 相同的功能,但是更加的灵活。
257
+
258
+ ``` java
259
+ private static void countDownLatch() throws Exception {
260
+ int thread = 3 ;
261
+ long start = System . currentTimeMillis();
262
+ final CountDownLatch countDown = new CountDownLatch (thread);
263
+ for (int i= 0 ;i< thread ; i++ ){
264
+ new Thread (new Runnable () {
265
+ @Override
266
+ public void run () {
267
+ LOGGER . info(" thread run" );
268
+ try {
269
+ Thread . sleep(2000 );
270
+ countDown. countDown();
271
+
272
+ LOGGER . info(" thread end" );
273
+ } catch (InterruptedException e) {
274
+ e. printStackTrace();
275
+ }
276
+ }
277
+ }). start();
278
+ }
279
+
280
+ countDown. await();
281
+ long stop = System . currentTimeMillis();
282
+ LOGGER . info(" main over total time={}" ,stop- start);
283
+ }
284
+ ```
285
+
286
+ CountDownLatch 也是基于 AQS(AbstractQueuedSynchronizer) 实现的,更多实现参考 [ ReentrantLock 实现原理] ( http://crossoverjie.top/2018/01/25/ReentrantLock/ )
287
+
288
+ - 初始化一个 CountDownLatch 时告诉并发的线程,然后在每个线程处理完毕之后调用 countDown() 方法。
289
+ - 该方法会将 AQS 内置的一个 state 状态 -1 。
290
+ - 最终在主线程调用 await() 方法,它会知道 ` state == 0 ` 的时候返回。
291
+
217
292
## 线程响应中断
218
293
219
294
## 线程池 awaitTermination() 方法
0 commit comments