排好队,挨着跑
线程的顺序执行,有很多种方式,比如加锁、用join、使用newSingleThreadExecutor等,最近碰到一个场景:主线程A中需要按顺序执行 a1、a2、a3、a4四个函数(即a1执行完才可以开始a2),而 a1、a2、a3、a4每个函数中又开启了多线程处理业务。
因此存在问题:a1执行完的时候如何通知主线程,告诉a2 可以开启了。
既然分析出了问题,那就好办了,解决问题即可,这里使用java关键词volatile
volatile:是一个变量修饰符,被用来修饰会被不同线程访问和修改的变量。
解决思路:
1.定义全局变量并初始化为 flag = 0;
2.a1执行完修改将变量改为1;a2执行完将其改为2;以此类推;
3.主线程判断某一步执行完才开始下一步,否则sleep(300)
4.当前线程是否执行结束,使用原子计数器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;}});}}}
执行结果
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---------------------
评论
