全栈程序猿的成长

线程的顺序执行

2022-08-05  本文已影响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---------------------

上一篇下一篇

猜你喜欢

热点阅读