美文网首页JAVA基础程序员
如何控制多线程执行的顺序?

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

作者: wwbovo | 来源:发表于2019-04-04 16:48 被阅读7次

    先看一段代码:

    public class TestThread {
        static Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程1");
            }
        });
        static Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程2");
            }
        });
        static Thread thread3=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程3");
            }
        });
        public static void main(String[] args) {
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
    

    执行结果:

    我是线程2
    我是线程3
    我是线程1
    

    可以看到线程的执行顺序是随机的。
    查阅资料控制多线程执行顺序有以下两种方法:

    方法1:调用join方法

    public class TestThread {
        static Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程1");
            }
        });
        static Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程2");
            }
        });
        static Thread thread3=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程3");
            }
        });
        public static void main(String[] args) throws Exception{
            thread1.start();
            thread1.join();
            thread2.start();
            thread2.join();
            thread3.start();
        }
    }
    

    执行结果:

    我是线程1
    我是线程2
    我是线程3
    

    可以看到线程按照顺序执行。

    join方法:让主线程等待子线程运行结束后再继续运行

    原理剖析:在main方法中,先是调用了t1.start方法,启动t1线程,随后调用t1的join方法,main所在的主线程就需要等待t1子线程中的run方法运行完成后才能继续运行,所以主线程卡在t2.start方法之前等待t1程序。等t1运行完后,主线程重新获得主动权,继续运行t2.start和t2.join方法,与t1子线程类似,main主线程等待t2完成后继续执行,如此执行下去,join方法就有效的解决了执行顺序问题。因为在同一个时间点,各个线程是同步状态。

    方法2:Excutors.newSingleThreadExecutor()

    public class TestThread {
        static Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程1");
            }
        });
        static Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程2");
            }
        });
        static Thread thread3=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是线程3");
            }
        });
    
        static ExecutorService executorService = Executors.newSingleThreadExecutor();
    
        public static void main(String[] args) throws Exception{
            executorService.submit(thread1);
            executorService.submit(thread2);
            executorService.submit(thread3);
        }
    }
    

    执行结果:

    我是线程1
    我是线程2
    我是线程3
    

    可以看到线程按照顺序执行。
    原理剖析:
    利用并发包里的Excutors的newSingleThreadExecutor产生一个单线程的线程池,而这个线程池的底层原理就是一个先进先出(FIFO)的队列。代码中executor.submit依次添加了123线程,按照FIFO的特性,执行顺序也就是123的执行结果,从而保证了执行顺序。

    相关文章

      网友评论

        本文标题:如何控制多线程执行的顺序?

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