精华内容
下载资源
问答
  • 14 如何多个线程顺序执行

    千次阅读 2020-08-12 21:48:06
    如何控制线程的执行顺序? 方法一:使用join()方法让一个线程强制运行 调用一个线程的join()方法就可以让这个线程强制运行,并且它会阻塞主线程的运行。 原理:调用join方法,会调用join(0)方法,当参数为0时,会...

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

    方法一:使用join()方法让一个线程强制运行

    调用一个线程的join()方法就可以让这个线程强制运行,并且它会阻塞主线程的运行。
    原理:调用join方法,会调用join(0)方法,当参数为0时,会调用wait方法,使主线程阻塞,等待子线程执行完毕后,主线程结束等待,继续执行。

    wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。
    在这里插入图片描述

    public static void main(String[] args) {
    try {
                System.out.println("main开始运行");
                thread1.start();
                thread1.join(); //让thread1强制执行完毕后,才可以执行后面的代码
                thread2.start();
                thread2.join();
                thread3.start();
                thread3.join();
                System.out.println("main运行结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    方法二:使用juc包下的Executors线程池保证子线程按顺序执行

    使用Executors中的newSingleThreadExecutor()方法,创建一个单线程的线程池,
    将线程用排队的方式扔进一个线程池里,让所有的任务以单线程的模式,按照FIFO先进先出,也可以达到控制线程执行顺序的目的。

    static ExecutorService executorService = 
      Executors.newSingleThreadExecutor();
    public static void main(String[] args) {
            System.out.println("main开始运行");
            executorService.submit(thread1);
            executorService.submit(thread2);
            executorService.submit(thread3);
            executorService.shutdown();
            System.out.println("main运行结束");
        }
    
    方法三:用CountdownLach保证子线程按顺序执行

    利用CountdownLach可以使一个线程等待其他线程完成某件事情之后才能执行,
    它的内部提供了一个计数器,在构造CountdownLach时必须指定计数器的初始值,且计数器的初始值必须>=0。另外它还提供了一个countDown方法来操作计数器的值,每调用一次countDown方法计数器都会减1,直到计数器的值减为0时,所有因调用await方法而阻塞的线程都会被唤醒。这就是CountDownLatch的内部机制。

    public class ThreadTest2 {
     
    // T1、T2、T3三个线程顺序执行
    public static void main(String[] args) {
        CountDownLatch c0 = new CountDownLatch(0); //计数器为0
        CountDownLatch c1 = new CountDownLatch(1); //计数器为1
        CountDownLatch c2 = new CountDownLatch(1); //计数器为1
     
        Thread t1 = new Thread(new Work(c0, c1));
        //c0为0,t1可以执行。t1的计数器减1
     
        Thread t2 = new Thread(new Work(c1, c2));
        //t1的计数器为0时,t2才能执行。t2的计数器c2减1
     
        Thread t3 = new Thread(new Work(c2, c2));
        //t2的计数器c2为0时,t3才能执行
     
        t1.start();
        t2.start();
        t3.start();
     
    }
     
    //定义Work线程类,需要传入开始和结束的CountDownLatch参数
    static class Work implements Runnable {
        CountDownLatch c1;
        CountDownLatch c2;
     
        Work(CountDownLatch c1, CountDownLatch c2) {
            super();
            this.c1 = c1;
            this.c2 = c2;
        }
     
        public void run() {
            try {
                c1.await();//前一线程为0才可以执行
                System.out.println("thread start:" + Thread.currentThread().getName());
                c2.countDown();//本线程计数器减少
            } catch (InterruptedException e) {
            }
     
        }
     }
    }
    
    方法四:用BlockingQueue

    将线程放入到BlockingQueue中,依次取出BlockingQueue中的线程,执行线程的start方法。

    阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。

    public class ThreadTest4 {
    // T1、T2、T3三个线程顺序执行
    public static void main(String[] args) {
        //blockingQueue保证顺序
        BlockingQueue<Thread> blockingQueue = new LinkedBlockingQueue<Thread>();
        Thread t1 = new Thread(new Work());
        Thread t2 = new Thread(new Work());
        Thread t3 = new Thread(new Work());
     
        blockingQueue.add(t1);
        blockingQueue.add(t2);
        blockingQueue.add(t3);
     
        for (int i=0;i<3;i++) {
            Thread t = null;
            try {
                t = blockingQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t.start();
            //检测线程是否还活着
            while (t.isAlive());
        }
    }
     
    static class Work implements Runnable {
     
        public void run() {
            System.out.println("thread start:" + Thread.currentThread().getName());
        }
     }
    }
    
    展开全文
  • 如何保证多线程顺序执行

    千次阅读 2019-03-20 21:39:46
    举个例子:现有T1、T2、T3、主线程四个线程,如何安照T1执行完才执行T2、T2执行完才执行T3、T3执行完最后执行主线程才结束? 答案:使用join()方法,让其他线程等待。使用join的线程会独占执行资源,直到使用完毕,...

    多线程情况下由于会有CPU在不同线程之间的来回切换,各个线程的执行结果会产生交叉 。

    举个例子:现有T1、T2、T3、主线程四个线程,如何安照T1执行完才执行T2、T2执行完才执行T3、T3执行完最后执行主线程才结束?

    答案:使用join()方法,让其他线程等待。使用join的线程会独占执行资源,直到使用完毕,其它线程才能获取执行权。

    代码示例如下:  

    public class JoinDemo {
    
    	public static void main(String[] args) throws InterruptedException {
    		// 线程t1
    		Thread t1 = new Thread(new Runnable() {
    			public void run() {
    				for (int i = 0; i < 5; i++) {
    				    System.out.println("-----T1-----" + i);
    				}
    			}
    		},"t1");
    		t1.start();
    		// 使用join让其他线程等待,本线程执行完成后其它线程才能执行
    		t1.join();
    
    		// 线程t2
    		Thread t2 = new Thread(new Runnable() {
    			public void run() {
    				for (int i = 0; i < 5; i++) {
    				    System.out.println("-----T2-----" + i);
    				}
    			}
    		},"t2");
    		t2.start();
    		// 使用join让其他线程等待,本线程执行完成后其它线程才能执行
    		t2.join();
    
    		// 线程t3
    		Thread t3 = new Thread(new Runnable() {
    			public void run() {
    				for (int i = 0; i < 5; i++) {
    				    System.out.println("-----T3-----" + i);
    				}
    			}
    		},"t3");
    		t3.start();
    		// 使用join让其他线程等待,本线程执行完成后其它线程才能执行
    		t3.join();
    
    		System.out.println("-----main------");
    
    	}
    
    }

    执行结果截图:

    当然join()方法,也可以设置一个时间参数。

    例如:
     

    Thread t1 = new Thread();
    
    t1 .start(); 
    
    t1 .join(100) ;
    
    Thread t2 = new Thread();
    
    t2.start();

    表示经过100ms后,不管t1有没有执行完毕,t2都会获得执行权。

     

    展开全文
  • Thread提供了一个让一个线程等待另一个线程执行完的方法——join();当线程A调用B线程join()方法后,线程A将会阻塞,只有等B线程执行完后在会执行线程A public class ThreadMain { public static void main...

    如何保证多个线程同时执行

    CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,向下减计数器的方法:countdown()。

    public class Demo1 {
    
        public static void main(String[] args) {
            int threadCount = 3;
            //计数器设置为1
            CountDownLatch countDownLatch = new CountDownLatch(1);
            for (int i = 0; i < threadCount; i++) {
                new Thread(() -> {
                    try {
                        //阻塞
                        countDownLatch.await();
                        System.out.println(Thread.currentThread().getName() + "线程开始时间:" + System.currentTimeMillis());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }).start();
            }
            System.out.println("计数器减一,变成0,开始执行三个子线程");
            countDownLatch.countDown();
            
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("主线程执行结束");
        }
    }

    执行结果如下:

    可以看到三个线程开始时间一直(可能会有纳米级的误差)。

     

    如何保证多个线程在并发下依次执行

    使用volatile 和 static来标记一个变量,实现demo如下:

    public class Demo2 {
    
        private volatile static int flag = 1;
    
        public static void main(String[] args) {
            Thread th1 = new Thread(() -> {
                    while (true) {
                        if (flag == 1) {
                            try {
    //                            Thread.sleep(1000L);
                                System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            flag = 2;
                            return;
                        }
    
                    }
            });
    
            Thread th2 = new Thread(() -> {
                while (true) {
                    if (flag == 2) {
                        try {
    //                        Thread.sleep(1000L);
                            System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        flag = 3;
                        return;
                    }
    
                }
            });
    
            Thread th3 = new Thread(() -> {
                while (true) {
                    if (flag == 3) {
                        try {
    //                        Thread.sleep(1000L);
                            System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        flag = 1;
                        return;
                    }
                }
            });
    
            th1.start();
            th2.start();
            th3.start();
    
        }
    }

    结果如下:

    这里flag必须要用volatile修饰

    如何保证多个线程有序交错执行

    使用Semaphore 类;

    public class Demo3 {
    
        //设置信号量为1
        private static Semaphore semaphore1 = new Semaphore(1);
        private static Semaphore semaphore2 = new Semaphore(1);
        private static Semaphore semaphore3 = new Semaphore(1);
    
        public static void main(String[] args) {
            int size = 10;
    
            try {
                //获取信号量,当被获取后不释放将会卡住
                semaphore2.acquire();
                semaphore3.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            Thread th1 = new Thread(() -> {
                for (int i = 0; i < size; i++) {
                    try {
                        //第一次进来由于2和3被获取了,其他线程被卡住,所以这里能获取到
                        semaphore1.acquire();
                        System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    //释放第二个信号量
                    semaphore2.release();
                }
            });
    
            Thread th2 = new Thread(() -> {
                for (int i = 0; i < size; i++) {
                    try {
                        semaphore2.acquire();
                        System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    semaphore3.release();
                }
            });
    
            Thread th3 = new Thread(() -> {
                for (int i = 0; i < size; i++) {
                    try {
                        semaphore3.acquire();
                        System.out.println("执行线程" + Thread.currentThread().getName() + "业务");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    semaphore1.release();
                }
            });
    
            th1.start();
            th2.start();
            th3.start();
    
        }
    }

    结果可看到几个线程是依次轮询执行:

    Semaphore并不控制线程之间的关系;它表示的是一个可使用资源的数目,如上new Semaphore(1),则表示创建资源数为1,当调用acquire()方法后,资源数为0,当有其他线程再次调用acquire()时,因为这时没有资源了,所以这里会卡住住,等到调用release()方法后,归还资源,其他线程才会去执行。它也被更多地用来限制流量,类似阀门的功能。

    展开全文
  • java中如何保证多线程顺序执行

    千次阅读 2019-07-30 17:59:47
    如何保证多线程顺序执行 代码: public class ThreadDemo { static Thread threadA = new Thread(()->{ System.out.println("线程A"); }); ​ static Thread threadB = new Thread(()->{ System.out....

    如何保证多线程顺序执行

    代码:

    public class ThreadDemo {
     static Thread threadA = new Thread(()->{
     System.out.println("线程A");
     });
    ​
     static Thread threadB = new Thread(()->{
     System.out.println("线程B");
     });
     
     static Thread threadC = new Thread(() -> {
     System.out.println("线程C");
     });
     public static void main(String[] args){
     threadA.start();
     threadB.start();
     threadC.start();
     }
     }
     输出结果:
     线程A
     线程C
     线程B
     输出结果每次不确定
    

    解决方案一

    1、join方法

    public class ThreadDemo {
     static Thread threadA = new Thread(()->{
     System.out.println("线程A");
     });
    ​
     static Thread threadB = new Thread(()->{
     System.out.println("线程B");
     });
     
     static Thread threadC = new Thread(() -> {
     System.out.println("线程C");
     });
     public static void main(String[] args) throws InterruptedException {
     threadA.start();
     threadA.join();
     threadB.start();
     threadB.join();
     threadC.start();
     threadC.join();
     }
     }
     输出结果:
     线程A
     线程B
     线程C
    

    分析,join原理

    a.查看jdk文档,join作用是让主线程等待子线程执行完之后再执行

    java中如何保证多线程顺序执行

    jdk:join()定义

    b.查看源码

    join()的调用

    java中如何保证多线程顺序执行

     

    java中如何保证多线程顺序执行

     

    位于main Thread的main()中,所以这里当然就是阻塞main Thread了。所以threadA.join()调用后,main Thread会阻塞起来。

    2、Executors.newSingleThreadExecutor

    public class ThreadDemo {
     static Thread threadA = new Thread(()->{
     System.out.println("线程A");
     });
    ​
     static Thread threadB = new Thread(()->{
     System.out.println("线程B");
     });
    ​
     static Thread threadC = new Thread(() -> {
     System.out.println("线程C");
     });
     static ExecutorService executors = Executors.newSingleThreadExecutor();
     public static void main(String[] args) throws InterruptedException {
    ​
     executors.submit(threadA);
     executors.submit(threadB);
     executors.submit(threadC);
     executors.shutdown();
     }
    }
    结果:
    线程A
    线程B
    线程C
    ​
    

    分析:直接查看源代码

    java中如何保证多线程顺序执行

     

    java中如何保证多线程顺序执行

     

    采用FIFO方式,保证每次只运行一个线程

    最后分享一个我自己的后端技术群,群里自己收集了很多Java架构资料,大家可以进群即可免费领取,群号:680075317,也可以进群一起交流,比如遇到技术瓶颈、面试不过的,大家一些交流学习!

    展开全文
  • 文章目录 ReentrantLock+Condition方式实现 Synchronized+wait/notifyAll方式实现 两者对比 ReentrantLock+Condition方式实现 public class ... 两者对比 使用ReentrantLock+Condition可以更准确的控制唤醒哪一个线程;...
  • 如何保证多个线程按一定顺序执行

    千次阅读 2019-05-13 14:32:19
    假设现在有三个线程t1、t2和t3 让t2在t1完成后执行,t3在t2完成后执行 自定义Thread类 public class Thread extends java.lang.Thread { private String str ; private int time; public Thread(String str,int ...
  • 多线程顺序执行的几种方法

    万次阅读 多人点赞 2019-09-05 14:23:58
    文章介绍4种方法,简单易懂,通过4demo抛砖引玉。 目录 在子线程中通过join()方法指定顺序 在主线程中通过join()方法指定顺序 ...通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。举例:在...
  • 多线程并发保证线程顺序执行

    千次阅读 2020-01-04 17:14:25
    2.真正的业务需求,如解析XML 我们想并发执行xml下多个节点,但是我们需要解析完成后再继续下不操作,如果节点中有依赖关系那我们就必须要保证一些顺序执行。 一.单纯面试来说 可实现的方式 1.join关键字 关键...
  • 题目要求:创建三个线程,每个线程分别打印ABC,并按照ABC的顺序执行十次 题目可以使用多种不同的方式解决,下面我们分别使用 Condition 等待唤醒机制、Semaphore 信号量、CountDownLatch 闭锁、Thread.join() 方法...
  • java 多线程顺序执行

    千次阅读 2019-06-14 16:22:44
    这道阿里巴巴线程面试题,你学会了没有? 置顶2019年06月14日 15:43:55XingXing_Java阅读数 447 点关注,不迷路;持续更新Java相关技术及资讯!...通过N个线程顺序循环打印从0至100,如给定N=3则输出: threa...
  • 如何让多个线程按照顺序执行

    千次阅读 2018-10-12 19:21:20
     如果有a,b,c三个线程,我们依次执行这三个线程。因为不保证有序性,可能执行出来是混乱的 解决如下: 第一种使用join()方法,这个方法的作用是,让当前执行线程等待直到调用join方法的线程结束运行 代码如下:...
  • Python 多个线程按先后顺序执行,并保持各子线程和主线程的通信 摘要 最近有个项目使用pyqt5写的界面,界面展示部分作为项目的主线程,另外通过调用Thread,传入不同的参数又设置了五个子线程,因为第一个子线程的...
  • 多线程多任务顺序执行

    千次阅读 2018-08-03 16:44:33
    ios开发中会用到任务顺序执行,执行完毕在执行其他的线程任务,在面试中也会经常被问到,我这里就将方法代码记录下来作为一笔记 我这里将通过信号量和GCD的Group实现任务顺序执行 1.通过信号量来实现 //通过...
  • Android中让多个线程顺序执行探究

    千次阅读 2015-09-14 10:27:15
    前言: 不知道从什么时候开始,越来越喜欢把平时学到的一些东西...对于这种问题,我更的是把写博客看成自己技术的总结,因为你总结一技术,肯定是需要查大量资料,而在此过程中你不仅巩固了以前的知识也会不断的
  • newSingleThreadExecutor 这线程池,保证线程里面的任务依次执行,这让我发现了新大陆, 立马实践了一下,发现不负所望; public class TestJoin { public static void main(String[] args) throws ...
  • Java—如何保证线程顺序执行

    千次阅读 2020-01-08 18:41:09
    多个线程执行任务时,可以通过Thread.join()方法保证多线程的执行顺序,其内部是通过调用主线程的wait方法,使主线程等待;当子线程执行完成后,再唤醒主线程。 下面写一个简单的实例:创建ABCD四个线程,每个线程...
  • jmeter 多个线程执行顺序

    千次阅读 2019-09-09 15:45:13
    当有多个线程组运行时: 1.如果不勾选独立运行每个线程组,则运行顺序是按每个线程组首字母 的顺序运行 2.勾选独立运行每个线程组,则运行顺序是按照自己设置的线程组的顺序执行 ...
  • 这个题目其实就是指定多个线程执行顺序,基本思路如下: 设定一个orderNum,每个线程执行结束之后,更新orderNum,指明下一个要执行的线程。并且唤醒所有的等待线程。 在每一个线程的开始,要while判断...
  • jmeter之多个线程顺序执行操作

    千次阅读 2019-06-22 09:15:53
    1.测试计划设置:独立运行每个线程组 2.结果树: 目前在两个线程组中,分别加入了两个http信息头管理器,用来记录用户标识,设置独立运行每个线程组只能将每个线程组单独单独运行,无法进行状态和参数的传递。 .....
  • 1.有A、B、C、D四个线程,A线程输出A, B线程输出B, C线程输出C,D线程输出D,要求, 同时启动四个线程, 按顺序输出ABCD; 本题主要通过join方法来实现顺序输出ABCD。 代码如下: package thread; /** * @author ...
  • 用Jmeter做自动化测试,一个测试计划中添加多个线程组, 每个线程组的功能测试,希望是一个线程组执行完毕后,接着执行下一个线程组下的请求 Jmeter默认多个线程组之间是并行关系 需要在测试计划下勾选Run ...
  • 如何确保三个线程顺序执行

    千次阅读 2018-07-18 06:34:51
     thread.Join把指定的线程加入到当前线程,可以将两交替执行的线程合并为顺序执行线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。 t.join(); //调用join方法,等待...
  • C# 不使用Task实现的多线程顺序执行

    千次阅读 2018-06-19 15:10:53
    线程有很好的并发性即无序性,在某些特殊情况下需要用到线程然而又要使其具备顺序性,这种时候就有了一特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项目中如果...
  • 多线程控制线程执行顺序

    千次阅读 2018-04-19 00:19:20
    如何控制线程执行顺序?...先来一段多线程执行的代码。public class Test { public static void main(String[] args) { Thread t1 = new Thread(new MyThread1()); Thread t2 = new Thread(...
  • 面试题:如何让线程顺序执行

    万次阅读 2019-09-22 10:23:52
    本文使用了8种方法实现在多线程中让线程顺序运行的方法,涉及到多线程中许多常用的方法,不止为了知道如何让线程顺序运行,更是让读者对多线程的使用有更深刻的了解。使用的方法如下: [1] 使用线程的join方法 ...
  • 在一个脚本文件中,如果有多个线程组,并且想让他们从上到下依次执行,只需在测试计划页面,勾选“独立运行每个线程组”即可 “Run teardown thread groups after shutdown of main threads”的意思是:主线程关闭...
  • C#多线程顺序依赖执行控制

    千次阅读 2018-10-22 15:57:09
    在开发过程中,经常需要多个任务并行的执行的场景,同时任务之间又需要先后依赖的关系。针对这样的处理逻辑,通常会采用多线程的程序模型来实现。   比如A、B、C三个线程,A和B需要同时启动,并行处理,且B需要...
  • 需求是:main里面的3方法,要按顺序执行。 public class TestThread1 implements Runnable{ public void doSomething(){ ThreadPool pool = new ThreadPool(); for (int i = 0; i ; i++) { pool....
  • #等待到该线程结束,才开始执行下一个线程 print "%s thread No.%d ended" %(ctime(),tid+ 1 ) sleep( 1 ) end_time=time.time() #结束计时 print( "Total time:{}" .format(end_time-start_time)) if ...
  • 个线程执行多个任务,要按照顺序执行import java.util.concurrent.ArrayBlockingQueue;/** * 一个线程执行多个任务,要按照顺序执行,怎么去实现? * 分析: * 多个人任务-->线程 * 要按照顺序执行--》就需要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 514,692
精华内容 205,876
关键字:

如何保证多个线程顺序执行