排好隊(duì),挨著跑
線程的順序執(zhí)行,有很多種方式,比如加鎖、用join、使用newSingleThreadExecutor等,最近碰到一個(gè)場(chǎng)景:主線程A中需要按順序執(zhí)行 a1、a2、a3、a4四個(gè)函數(shù)(即a1執(zhí)行完才可以開始a2),而 a1、a2、a3、a4每個(gè)函數(shù)中又開啟了多線程處理業(yè)務(wù)。
因此存在問題:a1執(zhí)行完的時(shí)候如何通知主線程,告訴a2?可以開啟了。
既然分析出了問題,那就好辦了,解決問題即可,這里使用java關(guān)鍵詞volatile
volatile:是一個(gè)變量修飾符,被用來修飾會(huì)被不同線程訪問和修改的變量。
解決思路:
1.定義全局變量并初始化為 flag = 0;
2.a1執(zhí)行完修改將變量改為1;a2執(zhí)行完將其改為2;以此類推;
3.主線程判斷某一步執(zhí)行完才開始下一步,否則sleep(300)
4.當(dāng)前線程是否執(zhí)行結(jié)束,使用原子計(jì)數(shù)器AtomicInteger
主線程示例
package com.mos.simple;import com.mos.simple.thread.ThreadFour;import com.mos.simple.thread.ThreadOne;import com.mos.simple.thread.ThreadThree;import com.mos.simple.thread.ThreadTwo;import lombok.extern.slf4j.Slf4j;4jpublic class TheadDemo {public volatile static int FLAG = 0;public static void main(String[] args) {for (int i = 0; i < 5; i++) {new TheadDemo().test(i);System.out.println("--------------------i am dividing line---------------------");}}public void test(int num) {ThreadOne threadOne = new ThreadOne();ThreadTwo threadTwo = new ThreadTwo();ThreadThree threadThree = new ThreadThree();ThreadFour threadFour = new ThreadFour();threadOne.test(num);threadWait(1);threadTwo.test(num);threadWait(2);threadThree.test(num);threadWait(3);threadFour.test(num);threadWait(4);FLAG = 0;}private void threadWait(int x) {while (FLAG != x) {try {Thread.sleep(300);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}
a1()示例
package com.mos.simple.thread;import com.mos.simple.TheadDemo;import lombok.extern.slf4j.Slf4j;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.Executors;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;@Slf4jpublic class ThreadOne {public void test(int num) {System.out.println("ThreadOne num is >> "+num);//線程池ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 60L, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(100), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());AtomicInteger count = new AtomicInteger(0);for (int i = 0; i < 100; i++) {threadPoolExecutor.execute(() -> {if (count.incrementAndGet() == 100) {TheadDemo.FLAG = 1;}});}}}
執(zhí)行結(jié)果
?ThreadOne num is >> 0ThreadTwo num is >> 0ThreadThree num is >> 0ThreadFour num is >> 0--------------------i am dividing line---------------------ThreadOne num is >> 1ThreadTwo num is >> 1ThreadThree num is >> 1ThreadFour num is >> 1--------------------i am dividing line---------------------ThreadOne num is >> 2ThreadTwo num is >> 2ThreadThree num is >> 2ThreadFour num is >> 2--------------------i am dividing line---------------------ThreadOne num is >> 3ThreadTwo num is >> 3ThreadThree num is >> 3ThreadFour num is >> 3--------------------i am dividing line---------------------ThreadOne num is >> 4ThreadTwo num is >> 4ThreadThree num is >> 4ThreadFour num is >> 4--------------------i?am?dividing?line---------------------
評(píng)論
圖片
表情
