排好队,挨着跑
小尘哥
共 3479字,需浏览 7分钟
·
2022-08-14 08:49
线程的顺序执行,有很多种方式,比如加锁、用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;
4j
public 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;
@Slf4j
public 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 >> 0
ThreadTwo num is >> 0
ThreadThree num is >> 0
ThreadFour num is >> 0
--------------------i am dividing line---------------------
ThreadOne num is >> 1
ThreadTwo num is >> 1
ThreadThree num is >> 1
ThreadFour num is >> 1
--------------------i am dividing line---------------------
ThreadOne num is >> 2
ThreadTwo num is >> 2
ThreadThree num is >> 2
ThreadFour num is >> 2
--------------------i am dividing line---------------------
ThreadOne num is >> 3
ThreadTwo num is >> 3
ThreadThree num is >> 3
ThreadFour num is >> 3
--------------------i am dividing line---------------------
ThreadOne num is >> 4
ThreadTwo num is >> 4
ThreadThree num is >> 4
ThreadFour num is >> 4
--------------------i am dividing line---------------------
评论