百度阿里经典面试题,三个线程按顺序执行
想要在子线程中让三个线程按顺序执行,最核心的思想是让线程等待,等到线程执行完毕之后,再去执行下一条。
1:join()
幸好Thread.join()方法就是这种机制,join()的方法就是先等待,在线程执行完毕之后才会返回,翻看源码可以更清晰的看到这一点,
所以第一种的实现方法如下所示,
public class JoinRealize { static class WorkersA implements Runnable { public void run() { System.out.println("正在运行A"); } } static class WorkersB implements Runnable { public void run() { System.out.println("正在运行B"); } } static class WorkersC implements Runnable { public void run() { System.out.println("正在运行C"); } } public static void main(String[] args) throws Exception{ for (int i = 0; i < 10; i++) { Thread thread1 = new Thread(new WorkersA()); thread1.start(); thread1.join(); Thread thread2 = new Thread(new WorkersB()); thread2.start(); thread2.join(); Thread thread3 = new Thread(new WorkersC()); thread3.start(); thread3.join(); } } }
很简单的实现了需求,接下来介绍第二种实现的方式,使用线程中的池化技术,只要在线程池中添加了唯一的线程,之后进池的都阻塞到队列中,也会实现这一功能
或者使用Executors中的newSingleThreadExecutor单线程也都是可以的,这种似乎更简单和更牛逼一点呢,但是我们探讨的不知这一点,开篇我说过,实现这个的主要思想就是让线程等待,之后通知线程执行,那么线程池中的execute方法,实际上也是通过等待通知模式实现功能的,接下来让我们着手自己写一个模拟的线程池,代码清单如下
class MyThreadPool<Job extends Runnable> extends Thread{ // 让线程池中的内置线程结束的标识位,由于线程池内置线程是一个死循环, // 所以让线程在我们想要的时候停下是很重要的 volatile boolean running = true; // 循环添加的线程Job private final LinkedList<Job> jobs = new LinkedList<Job>(); // 初始化线程,当初始化后,会让内置线程worker处于死循环,并一直执行到调用shutdown()方法之后 public MyThreadPool(int num) { initializeWorkers(num); } // 执行线程,并通知在worker中等待的线程执行 public void execute(Job job) { if (job != null) { synchronized (jobs) { jobs.addLast(job); jobs.notify(); } } } private void initializeWorkers(int num) { for (int i = 0; i < num; i++) { Worker worker = new Worker(); Thread thread = new Thread(worker,"MyThreadPool" + num); thread.start(); } } // 退出,表示位改变 public void shutdown() { running = false; } // 内置工作线程 class Worker implements Runnable { public void run() { Job job = null; // 死循环,在jobs为空或者表示为位为false的时候结束 while (!jobs.isEmpty() || running) { synchronized (jobs) { while (jobs.isEmpty()) { try { // jobs等待 jobs.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } job = jobs.removeFirst(); if (job != null) { //执行真正我们想要执行job的run()方法 job.run(); } } } } } }