线程的顺序执行

作者: 小尘哥 | 来源:发表于2022-08-05 14:29 被阅读0次

线程的顺序执行,有很多种方式,比如加锁、用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;
@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);
            log.info("--------------------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) {
        log.info("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;
                }
            });
        }

    }
}

执行结果

"D:\Program Files\Java\jdk1.8.0_291\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:60949,suspend=y,server=n -javaagent:C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2022.1\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;D:\codespace\chemors\mos-simple\target\classes;D:\Program Files\repo\org\springframework\boot\spring-boot-starter-web\2.7.2\spring-boot-starter-web-2.7.2.jar;D:\Program Files\repo\org\springframework\boot\spring-boot-starter\2.7.2\spring-boot-starter-2.7.2.jar;D:\Program Files\repo\org\springframework\boot\spring-boot\2.7.2\spring-boot-2.7.2.jar;D:\Program Files\repo\org\springframework\boot\spring-boot-autoconfigure\2.7.2\spring-boot-autoconfigure-2.7.2.jar;D:\Program Files\repo\org\springframework\boot\spring-boot-starter-logging\2.7.2\spring-boot-starter-logging-2.7.2.jar;D:\Program Files\repo\ch\qos\logback\logback-classic\1.2.11\logback-classic-1.2.11.jar;D:\Program Files\repo\ch\qos\logback\logback-core\1.2.11\logback-core-1.2.11.jar;D:\Program Files\repo\org\apache\logging\log4j\log4j-to-slf4j\2.17.2\log4j-to-slf4j-2.17.2.jar;D:\Program Files\repo\org\apache\logging\log4j\log4j-api\2.17.2\log4j-api-2.17.2.jar;D:\Program Files\repo\org\slf4j\jul-to-slf4j\1.7.36\jul-to-slf4j-1.7.36.jar;D:\Program Files\repo\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\Program Files\repo\org\yaml\snakeyaml\1.30\snakeyaml-1.30.jar;D:\Program Files\repo\org\springframework\boot\spring-boot-starter-json\2.7.2\spring-boot-starter-json-2.7.2.jar;D:\Program Files\repo\com\fasterxml\jackson\core\jackson-databind\2.13.3\jackson-databind-2.13.3.jar;D:\Program Files\repo\com\fasterxml\jackson\core\jackson-annotations\2.13.3\jackson-annotations-2.13.3.jar;D:\Program Files\repo\com\fasterxml\jackson\core\jackson-core\2.13.3\jackson-core-2.13.3.jar;D:\Program Files\repo\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.3\jackson-datatype-jdk8-2.13.3.jar;D:\Program Files\repo\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.3\jackson-datatype-jsr310-2.13.3.jar;D:\Program Files\repo\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.3\jackson-module-parameter-names-2.13.3.jar;D:\Program Files\repo\org\springframework\boot\spring-boot-starter-tomcat\2.7.2\spring-boot-starter-tomcat-2.7.2.jar;D:\Program Files\repo\org\apache\tomcat\embed\tomcat-embed-core\9.0.65\tomcat-embed-core-9.0.65.jar;D:\Program Files\repo\org\apache\tomcat\embed\tomcat-embed-el\9.0.65\tomcat-embed-el-9.0.65.jar;D:\Program Files\repo\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.65\tomcat-embed-websocket-9.0.65.jar;D:\Program Files\repo\org\springframework\spring-web\5.3.22\spring-web-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-beans\5.3.22\spring-beans-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-webmvc\5.3.22\spring-webmvc-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-aop\5.3.22\spring-aop-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-context\5.3.22\spring-context-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-expression\5.3.22\spring-expression-5.3.22.jar;D:\Program Files\repo\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar;D:\Program Files\repo\org\springframework\spring-core\5.3.22\spring-core-5.3.22.jar;D:\Program Files\repo\org\springframework\spring-jcl\5.3.22\spring-jcl-5.3.22.jar;D:\Program Files\repo\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;D:\Program Files\JetBrains\IntelliJ IDEA 2022.1.2\lib\idea_rt.jar" com.mos.simple.TheadDemo
Connected to the target VM, address: '127.0.0.1:60949', transport: 'socket'
14:29:09.983 [main] INFO com.mos.simple.thread.ThreadOne - ThreadOne num is 0
14:29:10.497 [main] INFO com.mos.simple.thread.ThreadTwo - ThreadTwo num is 0
14:29:10.800 [main] INFO com.mos.simple.thread.ThreadThree - ThreadThree num is 0
14:29:11.102 [main] INFO com.mos.simple.thread.ThreadFour - ThreadFour num is 0
14:29:11.404 [main] INFO com.mos.simple.TheadDemo - --------------------i am dividing line---------------------
14:29:11.404 [main] INFO com.mos.simple.thread.ThreadOne - ThreadOne num is 1
14:29:11.706 [main] INFO com.mos.simple.thread.ThreadTwo - ThreadTwo num is 1
14:29:12.006 [main] INFO com.mos.simple.thread.ThreadThree - ThreadThree num is 1
14:29:12.310 [main] INFO com.mos.simple.thread.ThreadFour - ThreadFour num is 1
14:29:12.612 [main] INFO com.mos.simple.TheadDemo - --------------------i am dividing line---------------------
14:29:12.612 [main] INFO com.mos.simple.thread.ThreadOne - ThreadOne num is 2
14:29:12.913 [main] INFO com.mos.simple.thread.ThreadTwo - ThreadTwo num is 2
14:29:13.215 [main] INFO com.mos.simple.thread.ThreadThree - ThreadThree num is 2
14:29:13.516 [main] INFO com.mos.simple.thread.ThreadFour - ThreadFour num is 2
14:29:13.818 [main] INFO com.mos.simple.TheadDemo - --------------------i am dividing line---------------------
14:29:13.818 [main] INFO com.mos.simple.thread.ThreadOne - ThreadOne num is 3
14:29:14.120 [main] INFO com.mos.simple.thread.ThreadTwo - ThreadTwo num is 3
14:29:14.421 [main] INFO com.mos.simple.thread.ThreadThree - ThreadThree num is 3
14:29:14.722 [main] INFO com.mos.simple.thread.ThreadFour - ThreadFour num is 3
14:29:15.025 [main] INFO com.mos.simple.TheadDemo - --------------------i am dividing line---------------------
14:29:15.025 [main] INFO com.mos.simple.thread.ThreadOne - ThreadOne num is 4
14:29:15.326 [main] INFO com.mos.simple.thread.ThreadTwo - ThreadTwo num is 4
14:29:15.627 [main] INFO com.mos.simple.thread.ThreadThree - ThreadThree num is 4
14:29:15.927 [main] INFO com.mos.simple.thread.ThreadFour - ThreadFour num is 4
14:29:16.228 [main] INFO com.mos.simple.TheadDemo - --------------------i am dividing line---------------------

相关文章

  • python——多线程

    多线程-threading 子类完成创建多线程 线程的执行顺序也是主线程和各个子线程随机执行,顺序不确定 线程对全...

  • 线程按指定顺序执行

    在多线程中线程的执行是CPU随机调度的,无法指定线程的执行顺序,比如我们要让多线程按顺序执行输出 这段代码的输出顺...

  • Java并发编程(一)如何保证线程顺序执行

    只要了解过多线程,我们就知道线程开始的顺序跟执行的顺序是不一样的。如果只是创建三个线程然后执行,最后的执行顺序是不...

  • iOS 多线程-CGD

    串行队列同步执行,不开启新线程,任务按顺序执行 串行队列异步执行,会开启新线程(1个),任务按照顺序执行 并行队列...

  • 线程的顺序执行

    线程的顺序执行,有很多种方式,比如加锁、用join、使用newSingleThreadExecutor等,最近碰到...

  • 1.2.1线程的启动顺序与start()的执行顺序无关

    执行start()方法的顺序不代表线程启动的顺序。 执行结果 摘选自 java多线程核心编程技术-1.2.1

  • 1-5linux系统编程——线程并发

    线程并发要求 线程并发性 同步:进程/线程中的部分指令需要按照一定的顺序前后执行异步:进程/线程之前的指令执行顺序...

  • 无标题文章

    同步任务: 优先级高,在线程中有执行顺序,不会开启新的线程 异步任务: 优先级低,在线程中执行没有顺序,看cpu闲...

  • Java 线程 - 线程顺序执行

    1 三个线程顺序打出abc 2 三个线程顺序打出abc 30次[Semaphore] 3 三个线程顺序打出abc ...

  • 如何控制多线程执行的顺序?

    先看一段代码: 执行结果: 可以看到线程的执行顺序是随机的。查阅资料控制多线程执行顺序有以下两种方法: 方法1:调...

网友评论

    本文标题:线程的顺序执行

    本文链接:https://www.haomeiwen.com/subject/jwjpwrtx.html