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

网友投稿 544 2022-08-01


目录在子线程中通过join(DOdpF)方法指定顺序在主线程中通过join()方法指定顺序通过倒数计时器CountDownLatch实现通过创建单一化线程池newSingleThreadExecutor()实现

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

在子线程中通过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(DOdpF1);

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

pDOdpFublic 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(); //使用完毕记得关闭线程池

}

}

输出结果:

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中for与foreach的区别(foreach和for的区别)
下一篇:java中RabbitMQ高级应用(java队列和rabbitmq队列区别)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~