精华内容
下载资源
问答
  • 2019-06-10 21:03:14

    1、使用Thread.join()方法

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B

    public class ThreadTest1 {
        public static void main(String[] args) {
            Thread t1 = new Thread(new Work(null));
            Thread t2 = new Thread(new Work(t1));
            Thread t3 = new Thread(new Work(t2));
            t1.setName("第一个");
            t2.setName("第二个");
            t3.setName("第三个");
            t1.start();
            t2.start();
            t3.start();
        }
        static class Work implements Runnable {
            private Thread thread;
            public Work(Thread thread) {
                this.thread = thread;
            }
            @Override
            public void run() {
                if (thread != null) {
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    execute();
                } else {
                    execute();
                }
            }
            private void execute() {
                System.out.println("线程" + Thread.currentThread().getName() + "执行");
            }
        }
    }
    

    执行结果:

    线程第一个执行
    线程第二个执行
    线程第三个执行
    
    Process finished with exit code 0
    

    2、使用线程池使用一个固定大小的线程池

    public class ThreadTest2 {
        private static ExecutorService es = Executors.newFixedThreadPool(1);
        public static void main(String[] args) {
            Work t1 = new Work("t1");
            Work t2 = new Work("t2");
            Work t3 = new Work("t3");
            es.submit(t1);
            es.submit(t2);
            es.submit(t3);
        }
        static class Work implements Runnable {
            private String key;
            public Work(String key) {
                this.key = key;
            }
            @Override
            public void run() {
                execute();
            }
            private void execute() {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程:" + Thread.currentThread().getName() + "执行" + key);
            }
        }
    }
    
    

    执行结果:

    线程:pool-1-thread-1执行t1
    线程:pool-1-thread-1执行t2
    线程:pool-1-thread-1执行t3
    
    Process finished with exit code 0
    

    注意:

    线程池shutdown方法和shutdownNow有区别,shutdown要等所有线程执行完后再关闭,shutdownNow将线程池内正在执行的线程强制停掉。

    更多相关内容
  • 主要介绍了Java 多线程有序执行的几种方法总结的相关资料,需要的朋友可以参考下
  • 并发学习(四) — 多线程有序执行

    千次阅读 2018-05-21 23:58:46
    前言:在看了这些多线程的知识之后,突发奇想到怎么让多线程有序执行呢?第一种:用Thread.join()方法来确定该线程执行完毕第二种:用线程池的队列来执行任务第一种方法:join方法是阻塞的,会一定等到取消或者...

    前言:

    在看了这些多线程的知识之后,突发奇想到怎么让多线程有序执行呢?

    第一种:用Thread.join()方法来确定该线程执行完毕

    第二种:用线程池的队列来执行任务

    第三种:用公共锁Object,配合wait/notifyAll方法,睡眠自己,唤醒另一个线程~


    join方法:

    join方法是阻塞的,会一定等到取消或者超时为止,这样就可以按顺序来。

    @Slf4j
    public class JoinExample {
    
        public static void main(String[] args) throws InterruptedException{
    
            log.info("{} is start", Thread.currentThread().getName());
    
            Thread t0 = new Thread(() -> {
                try{
                    log.info( "{} is Start,sleep 6 second", Thread.currentThread().getName());
                    Thread.sleep(6000);
                    log.info("{} is Completed", Thread.currentThread().getName());
                }catch (InterruptedException e){
                    log.error("exception", e);
                }
            });
            t0.start();
            t0.join();
    
            Thread t1 = new Thread(() -> {
                try{
                    log.info( "{} is Start,sleep 2 second", Thread.currentThread().getName());
                    Thread.sleep(2000);
                    log.info( "{} is Completed", Thread.currentThread().getName());
                }catch (InterruptedException e){
                    log.error("exception", e);
                }
            });
            t1.start();
            t1.join();
    
            log.info("{} is Completed", Thread.currentThread().getName() );
        }
    }
    


    再来一个,

    @Slf4j
    public class JoinExample1 {
    
        public static void main(String[] args) {
            final Thread t1 = new Thread(() -> {
                log.info("{} is first", Thread.currentThread().getName());
            },"线程1");
    
            final Thread t2 = new Thread(() -> {
                try {
                    t1.join();
                    log.info("{} is second", Thread.currentThread().getName());
                }catch (InterruptedException e){
                    log.info("exception", e);
                }
            },"线程2");
    
            final Thread t3 = new Thread(() -> {
                try {
                    t2.join();
                    log.info("{} is third", Thread.currentThread().getName());
                }catch (InterruptedException e){
                    log.info("exception", e);
                }
            },"线程3");
            
            t2.start();
            t3.start();
            t1.start();
    //顺序sart是没有关系的
        }
    }

    线程池newSingleThreadExecutor:

    @Slf4j
    public class JoinExample2 {
    
        public static void main(String[] args) {
    
            final Thread t1 = new Thread(() -> {
                log.info("{}, the first 运行了!", Thread.currentThread().getName());
            },"线程1");
    
    
            final Thread t2 = new Thread(() -> {
                log.info("{}, the second 运行了!", Thread.currentThread().getName());
            }, "线程2");
    
            final Thread t3 = new Thread(() -> {
                log.info("{}, the third 运行了!", Thread.currentThread().getName());
            }, "线程3");
    
            ExecutorService exec = Executors.newSingleThreadExecutor();
            exec.submit(t1);
            exec.submit(t2);
            exec.submit(t3);
            exec.shutdown();
        }
    }
    

    由于线程池中只有一个,所以默认就它一个能运行的线程~~

    展开全文
  • 多线程按顺序执行的几种方法

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

    文章介绍4种方法,简单易懂,通过4个demo抛砖引玉。

    目录

    在子线程中通过join()方法指定顺序

    在主线程中通过join()方法指定顺序

    通过倒数计时器CountDownLatch实现

    通过创建单一化线程池newSingleThreadExecutor()实现


    在子线程中通过join()方法指定顺序

    通过join()方法使当前线程“阻塞”,等待指定线程执行完毕后继续执行。举例:在线程thread2中,加上一句thread1.join(),其意义在于,当前线程2运行到此行代码时会进入阻塞状态,直到线程thread1执行完毕后,线程thread2才会继续运行,这就保证了线程thread1与线程thread2的运行顺序。

    public class ThreadJoinDemo {
        public static void main(String[] args) throws InterruptedException {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
    
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        thread1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("拿出一瓶牛奶!");
                }
            });
    
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        thread2.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("关上冰箱!");
                }
            });
    
            //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序。
            thread3.start();
            thread2.start();
            thread1.start();
    
        }
    }

    运行结果:

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!

    在主线程中通过join()方法指定顺序

    简单说一下子线程与主线程的区别,子线程指的是发生在Thread内部的代码,主线程指的是发生在main函数中的代码,我们可以在main函数中通过join()方法让主线程阻塞等待以达到指定顺序执行的目的。

    public class ThreadMainJoinDemo {
        public static void main(String[] args) throws InterruptedException {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
    
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("拿出一瓶牛奶!");
                }
            });
    
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("关上冰箱!");
                }
            });
    
            thread1.start();
            thread1.join();
            thread2.start();
            thread2.join();
            thread3.start();
        }
    }

    输出结果:

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!

    通过倒数计时器CountDownLatch实现

    CountDownLatch通过计数器提供了更灵活的控制,只要检测到计数器为0当前线程就可以往下执行而不用管相应的thread是否执行完毕。

    public class ThreadCountDownLatchDemo {
    
        private static CountDownLatch countDownLatch1 = new CountDownLatch(1);
    
        private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
    
        public static void main(String[] args) {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                    countDownLatch1.countDown();
                }
            });
    
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch1.await();
                        System.out.println("拿出一瓶牛奶!");
                        countDownLatch2.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch2.await();
                        System.out.println("关上冰箱!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            //下面三行代码顺序可随意调整,程序运行结果不受影响
            thread3.start();
            thread1.start();
            thread2.start();
        }
    }

    输出结果:

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!

    通过创建单一化线程池newSingleThreadExecutor()实现

    单线程化线程池(newSingleThreadExecutor)的优点,串行执行所有任务。

    public class ThreadPoolDemo {
    
       static ExecutorService executorService = Executors.newSingleThreadExecutor();
    
        public static void main(String[] args) {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
    
            final Thread thread2 =new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("拿出一瓶牛奶!");
                }
            });
    
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("关上冰箱!");
                }
            });
            executorService.submit(thread1);
            executorService.submit(thread2);
            executorService.submit(thread3);
            executorService.shutdown();        //使用完毕记得关闭线程池
        }
    
    }

    输出结果:

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!

     

    展开全文
  • 主要介绍了了解Java多线程的可见性与有序性,在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。,需要的朋友可以参考下
  • 名称: 多线程代码有序计时器 说明: 使用多线程委托方法,当一个方法执行完成后执行下一个方法,(方法可按设时间循环执行,当返回true则行下一个方法) 文件: Program.cs=>范例、HoshinoSortTime.cs=>主程序代码。
  • 其中有一个问题是老掉牙 的怎么实现多线程顺序执行~ 首先要理解多线程的几个生命周期,当调用Thread的start()方法,不代表这个线程就立刻执行了,而是这个线程进入了就绪状态,要执行的话还需要由CPU调度才能进入...

    前言

    昨天晚上面试一家公司,问的问题都比较基础,就想考考基础扎不扎实。
    其中有一个问题是老掉牙 的怎么实现多线程顺序执行~
    首先要理解多线程的几个生命周期,当调用Thread的start()方法,不代表这个线程就立刻执行了,而是这个线程进入了就绪状态,要执行的话还需要由CPU调度才能进入运行状态,其余的状态就不多说了……

    声明: 本文示例参照了

    让线程按顺序执行8种方法

    让多线程按顺序执行的几种方法

    一、Thread的join()方法

    当然,thread的join方法实现多线程顺序执行有两种方式,一种是在子线程内部调用join()方法,另一种是直接在主线程调用join()方法;写法上是主线程上调用join()更直观,谁先执行谁后执行一目了然。子线程内部调用的话,相对的要注意调用的顺序。

    1.子线程内部调用join()

    public class ThreadJoinDemo {
        public static void main(String[] args) throws InterruptedException {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
     
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        thread1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("拿出一瓶牛奶!");
                }
            });
     
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        thread2.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("关上冰箱!");
                }
            });
     
            //下面三行代码顺序可随意调整,程序运行结果不受影响,因为我们在子线程中通过“join()方法”已经指定了运行顺序(还有一个原因就是之前说的多线程的生命周期中有就绪状态,需要等待cpu调度,start并不意味着运行状态)。
            thread3.start();
            thread2.start();
            thread1.start();
        }
    }
    

    运行结果

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!
    

    2.在主线程中通过join()方法指定顺序

    public class ThreadMainJoinDemo {
        public static void main(String[] args) throws InterruptedException {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
     
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("拿出一瓶牛奶!");
                }
            });
     
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("关上冰箱!");
                }
            });
     
            thread1.start();
            thread1.join();
            thread2.start();
            thread2.join();
            thread3.start();
        }
    }
    

    运行结果

    打开冰箱!
    拿出一瓶牛奶!
    关上冰箱!
    

    注意: 这里得控制好顺序了,为什么要控制顺序呢,跟join()方法的源码有关,一起看看吧:

        public final void join() throws InterruptedException {
            join(0);
        }
    

    查看Thread源码可知,join()方法内部调用了join(0);
    进入如下方法,内部实现是调用了Object的wait(0),根据调用了join()方法的线程实例的存活状态,不断的循环判断是否让获得cpu资源的线程进入等待状态。

        public final synchronized void join(long millis)
        throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
    
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
    
            if (millis == 0) {
                while (isAlive()) {
                    wait(0);
                }
            } else {
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
    

    通过join()方法的源码,其实可以自己去利用wait()实现如何利用wait()完成线程顺序执行,这里不赘述。

    二、使用jdk5推出的线程池Executors创建单例的方法

    public class ThreadPoolDemo {
     
       static ExecutorService executorService = Executors.newSingleThreadExecutor();
     
        public static void main(String[] args) {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                }
            });
     
            final Thread thread2 =new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("拿出一瓶牛奶!");
                }
            });
     
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("关上冰箱!");
                }
            });
            executorService.submit(thread1);
            executorService.submit(thread2);
            executorService.submit(thread3);
            executorService.shutdown();        //使用完毕记得关闭线程池
        }
     
    }
    

    下面进入j.u.c包下的并发类,分水岭。。。

    三、CountDownLatch(倒计数)类

    CountDownLatch类的特点就是可以初始化设置一个state的值,每次调用countDown()方法进行减一,如果state没有减小到0就会被await()方法一直阻塞。利用CountDownLatch方法可以实现和join()方法子线程运用一样的妙处。当然,CountDownLatch类的缺点是state不能重置,只能初始化一次,意思就是减小到0后,就没用了。。。不能加回去。

    public class ThreadCountDownLatchDemo {
     
        private static CountDownLatch countDownLatch1 = new CountDownLatch(1);
     
        private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
     
        public static void main(String[] args) {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("打开冰箱!");
                    countDownLatch1.countDown();
                }
            });
     
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch1.await();
                        System.out.println("拿出一瓶牛奶!");
                        countDownLatch2.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
     
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch2.await();
                        System.out.println("关上冰箱!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
     
            //下面三行代码顺序可随意调整,程序运行结果不受影响
            thread3.start();
            thread1.start();
            thread2.start();
        }
    }
    

    四、CyclicBarrier(回环栅栏)类

    这个类对CountDownLatch不能重复计数进行了改进,实现了可重复计数,不用向上面例子那样创建多个CountDownLatch实例,这个只需创建一个实例,设置state的大小就可以了。
    当然,CyclicBarrier放在这也是大材小用,CyclicBarrier一般的使用场景是控制一组线程同时开始执行,就像跑步比赛一样,当所有运动员准备就绪才可以开始跑。

    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    /**
     * @author wwj
     * 使用CyclicBarrier(回环栅栏)实现线程按顺序运行
     */
    public class CyclicBarrierDemo {
    
        static CyclicBarrier barrier1 = new CyclicBarrier(2);
        static CyclicBarrier barrier2 = new CyclicBarrier(2);
    
        public static void main(String[] args) {
    
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("产品经理规划新需求");
                        //放开栅栏1
                        barrier1.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //放开栅栏1
                        barrier1.await();
                        System.out.println("开发人员开发新需求功能");
                        //放开栅栏2
                        barrier2.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            final Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //放开栅栏2
                        barrier2.await();
                        System.out.println("测试人员测试新功能");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            thread3.start();
            thread1.start();
            thread2.start();
        }
    }
    
    public class CyclicBarrierDemo {
    
        static class TaskThread extends Thread {
            
            CyclicBarrier barrier;
            
            public TaskThread(CyclicBarrier barrier) {
                this.barrier = barrier;
            }
            
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println(getName() + " 到达栅栏 A");
                    barrier.await();
                    System.out.println(getName() + " 冲破栅栏 A");
                    
                    Thread.sleep(2000);
                    System.out.println(getName() + " 到达栅栏 B");
                    barrier.await();
                    System.out.println(getName() + " 冲破栅栏 B");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args) {
            int threadNum = 5;
            CyclicBarrier barrier = new CyclicBarrier(threadNum, new Runnable() {
                
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " 完成最后任务");
                }
            });
            
            for(int i = 0; i < threadNum; i++) {
                new TaskThread(barrier).start();
            }
        }
        
    }
    

    打印结果

    Thread-1 到达栅栏 A
    Thread-3 到达栅栏 A
    Thread-0 到达栅栏 A
    Thread-4 到达栅栏 A
    Thread-2 到达栅栏 A
    Thread-2 完成最后任务
    Thread-2 冲破栅栏 A
    Thread-1 冲破栅栏 A
    Thread-3 冲破栅栏 A
    Thread-4 冲破栅栏 A
    Thread-0 冲破栅栏 A
    Thread-4 到达栅栏 B
    Thread-0 到达栅栏 B
    Thread-3 到达栅栏 B
    Thread-2 到达栅栏 B
    Thread-1 到达栅栏 B
    Thread-1 完成最后任务
    Thread-1 冲破栅栏 B
    Thread-0 冲破栅栏 B
    Thread-4 冲破栅栏 B
    Thread-2 冲破栅栏 B
    Thread-3 冲破栅栏 B
    

    五、Sephmore(信号量)类

    Sephmore类它是类似于回环栅栏,但是又不大一样,它里面的计数值叫许可,可以初始化许可的值,每个线程实例可以获取指定的许可个数,当这个线程执行完毕可以归还许可;让其他线程继续去获取许可执行线程内容;当获取不到许可的线程就会阻塞住,等待其他线程执行完,释放了许可,才能够往下执行。

    acquire():当前线程尝试去阻塞的获取1个许可证,此过程是阻塞的,当前线程获取了1个可用的许可证,则会停止等待,继续执行。

    release():当前线程释放1个可用的许可证。

    除了这两个方法外,Sephmore还有获取多个许可的方法,可以自行去查看源码。
    当然,Sephmore放在这里用确实是大材小用了,它一般的使用场景都是类似于数据库连接池的并发控制,取完后归还一样。

    import java.util.concurrent.Semaphore;
    /**
     * 使用Sephmore(信号量)实现线程按顺序运行
     */
    public class SemaphoreDemo {
        private static Semaphore semaphore1 = new Semaphore(1);
        private static Semaphore semaphore2 = new Semaphore(1);
        public static void main(String[] args) {
            final Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("产品经理规划新需求");
                    semaphore1.release();
                }
            });
    
            final Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore1.acquire();
                        System.out.println("开发人员开发新需求功能");
                        semaphore2.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            Thread thread3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore2.acquire();
                        thread2.join();
                        semaphore2.release();
                        System.out.println("测试人员测试新功能");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            System.out.println("早上:");
            System.out.println("测试人员来上班了...");
            thread3.start();
            System.out.println("产品经理来上班了...");
            thread1.start();
            System.out.println("开发人员来上班了...");
            thread2.start();
        }
    }
    

    执行结果

    早上:
    测试人员来上班了...
    产品经理来上班了...
    开发人员来上班了...
    产品经理规划新需求
    开发人员开发新需求功能
    测试人员测试新功能
    

    六、其实还有很多

    比如更高大上的AQS,锁,ReentrantLock配合Condition,涉及了两个队列,我比较头疼,一个是虚拟同步双向队列,一个是Condition的队列,只是我不太熟,理解不深刻,不敢拿出来卖,不过能使用后面三种基本上是对并发编程有一定理解了的。。。。。
    有兴趣可以去看看,这个可重入锁弄懂可是很加分的

    展开全文
  • java多线程实现顺序执行

    千次阅读 2022-02-14 14:06:42
    1.使用线程的join方法 public static void main(String[] args) { final Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("起床"); } }); final Thread t2
  • semaphore控制多线程循序执行,网上 找的例子更改的希望对大家有用
  • C#多线程顺序依赖执行控制

    千次阅读 2018-10-22 15:57:09
    针对这样的处理逻辑,通常会采用多线程的程序模型来实现。   比如A、B、C三个线程,A和B需要同时启动,并行处理,且B需要依赖A完成,在进行后续的处理,C需要B完成后开始处理。   针对这个场景,使用了...
  • spring 多线程队列执行

    2012-08-06 00:18:01
    spring 多线程队列执行
  • java 多线程顺序执行

    千次阅读 2019-06-14 16:22:44
    这道阿里巴巴多线程面试题,你学会了没有? 置顶2019年06月14日 15:43:55XingXing_Java阅读数 447 点关注,不迷路;持续更新Java相关技术及资讯!!! 前言 有个朋友问了我一道面试阿里的时候遇到的多线程...
  • Java多线程有序性(一)

    千次阅读 2018-05-18 15:08:09
    其实细想一下,多线程和单线程相比,出现问题不就是内存里面的值可能与预期值(单线程运行/串行运行)之间不一致嘛。所以一定至少要知道读写操作是怎么操作内存的!! 2.Java程序的运行顺序: 程序...
  • iOS 多线程 设定执行顺序

    千次阅读 2018-04-04 16:56:13
     那实际运用中,一般可以用dispatch这样来写,常见的网络请求数据多线程执行模型:    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    //子线程中开始网络请求数据   ...
  • 线程A调用B线程join()方法后,线程A将会阻塞,只有等B线程执行完后在会执行线程A public class ThreadMain { public static void main(String[] args) throws Exception { Thread myThread1 = new Threa...
  • 有序性是指,同一线程中的指令应该按顺序执行,而多线程中的指令未必按顺序执行。 示例 在下面的演示代码中,我们做了这样的事情: 首先,定义一个全局的静态变量 singleton ,使用1000个线程对调用 getInstance()...
  • 在使用多线程时,简单的IO操作有时满足不了我们的需求,我们需要有序的接收返回值,例如:调用第三方API 我这个栗子是调用TTS的在线合成API,先看一下结果吧: 左侧:正常的顺序执行,共进行了4次调用,最后的总...
  • 原因: 线程在并发环境中的执行顺序是随机无序的,并不能按照我们理想的效果进行输出,线程启动了只是告诉CPU它准备好了,具体的执行哪个线程需要CPU经过复杂的算法计算出来,所以多线程执行是随机无序的。...
  • 两个线程顺序有序执行,两个方法:1 用interrupt 和 sleep 2 用注释中的synchronized,signalAll ,sleep import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util....
  • 如何保证多线程的顺序执行

    千次阅读 2019-03-20 21:39:46
    多线程情况下由于会有CPU在不同线程之间的来回切换,各个线程的执行结果会产生交叉 。 举个例子:现有T1、T2、T3、主线程四个线程,如何安照T1执行完才执行T2、T2执行完才执行T3、T3执行完最后执行主线程才结束? ...
  • 利用join方法,让线程有序执行

    千次阅读 2018-01-29 13:51:39
    和wait()有点类似,join()方法可以让线程之间排队等待,按照一定的顺序执行。join方法是阻塞的,会一直等到取消或超时为止。假如现在有三个线程,main,t0,t1,要在main线程启动之后相继执行t0,t1,那么可以在...
  • 认识多线程

    2021-01-06 05:40:01
    认识多线程 多任务: 类似于生活中的一心二用,同时吃饭玩手机,或者边听歌边写作业 多线程: 类似于生活中的马路,为了提高使用的效率,多加了几条车道 普通方法调用和多线程 Process和Thread 程序是指令和数据的...
  • 题目描述:如何保证线程的顺序执行? join方式实现 join方式即使用Thread.join方法来实现。Thread.join含义当前线程需要等待previousThread线程终止之后才从thread.join返回。简单来说,就是线程没有执行完...
  • Thread:线程顺序执行的四种方式

    千次阅读 2020-11-26 21:59:15
    线程顺序执行的四种方式 1、通过监测信号 每个线程对应自己的一个信号,监测到信号就执行执行完就将信号更改为下一个线程的信号 2、通过FutureTask可以阻塞获取返回值的特性 顺序开启线程并获取返回值,线程将...
  • 如何保证二个线程有序交错进行?面试题:有A,B,C三个线程,如何保证三个线程同时执行?如何在并发情况下保证三个线程依次执行?如何保证二个线程有序交错进行?有A,B,C三个线程,如何保证三个线程同时执行?有A,B,C三个...
  • python同步应用:线程有序执行

    千次阅读 2017-08-12 22:43:59
    可以使用互斥锁完成个任务,有序的进程工作,这就是线程的同步 from threading import Thread, Lock import time mutex1= Lock() # 创建一个互斥锁 mutex2= Lock() # 创建一个互斥锁 mutex3= Lock() # ...
  • Java多线程有序性(二)

    千次阅读 2018-05-18 15:16:36
    有序性:指在什么情况下一个处理器上运行的一个线程执行的内存访问在另一处理器运行的另外一个线程看来是乱序的,乱序是指:内存访问的顺序看起来像是发生了变化。 我不随意揣测这个定义了,看不懂也没关系,我们...
  • python多线程学习-多线程下载图片

    千次阅读 2021-11-29 20:53:02
    目录开发工具知识点代码...多线程 网络编程 代码 # coding = utf-8 import threading import time import urllib.request # 线程停止变量 isrunning = True # 工作线程体函数 def workthread_body(): while isrun
  • 1使用join thread.join();使主线程等待thread执行完毕。 2使用Executors.newSingleThreadExecutor()。
  • 2)多线程之间并非同步,只保证执行顺序有序多线程之间是并发执行。 2、代码示例 package com.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 135,525
精华内容 54,210
关键字:

多线程有序执行