前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >排好队,挨着跑

排好队,挨着跑

作者头像
小尘哥
发布2022-12-07 10:30:34
3900
发布2022-12-07 10:30:34
举报
文章被收录于专栏:小尘哥的专栏小尘哥的专栏

线程的顺序执行,有很多种方式,比如加锁、用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

主线程示例

代码语言:javascript
复制
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;
@Slf4j
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()示例

代码语言:javascript
复制
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;
                }
            });
        }

    }
}

执行结果

代码语言:javascript
复制
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---------------------
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陌与尘埃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档