排好队,挨着跑

小尘哥

共 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;@Slf4jpublic 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---------------------


浏览 29
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报