面试官(你说说如何让“线程”按序执行())

时人不识凌云木,直待凌云始道高。这篇文章主要讲述面试官:你说说如何让“线程”按序执行?相关的知识,希望能为你提供帮助。
【面试官(你说说如何让“线程”按序执行())】当线程处于就绪状态时,等待被分配到CPU时间片然后才真正开始执行,由于每个线程开始的时间不确定,因此也就不能唯一确定线程的执行顺序。如果想让线程有序执行,主要思路就是让子线程的执行在主线程中串行化,想到了以下几种让线程按顺序执行的方法

面试官(你说说如何让“线程”按序执行())

文章图片

让线程按序执行的方法 JDK自带方法 join 等待线程执行终止的方法可以在主线程中调用子线程的join()方法,让子线程按序执行,代码如下:
public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("t1 do something"); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 do something"); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { System.out.println("t3 do something"); } }); t1.start(); // 主线程阻塞等待子线程执行完 t1.join(); t2.start(); // 主线程阻塞等待子线程执行完 t2.join(); t3.start(); // 主线程阻塞等待子线程执行完 t2.join(); }

并发工具类 CountDownLatchcountDownLatch.await()会阻塞调用线程直到 state==0。因此,可以利用这个特性使得子线程按序执行
private static CountDownLatch countDownLatch = new CountDownLatch(1); public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println("t1 do something"); countDownLatch.countDown(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 do something"); countDownLatch.countDown(); } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { System.out.println("t3 do something"); countDownLatch.countDown(); } }); t1.start(); // 主线程阻塞等待子线程执行完毕 countDownLatch.await(); t2.start(); // 主线程阻塞等待子线程 countDownLatch.await(); t3.start(); // 主线程阻塞等待子线程 countDownLatch.await(); }

CycleBarrier如下有三个任务,分三个步骤执行,依次按照线程123执行 barrier.await()方法,可以让当前线程等待其他线程执行完毕
static CyclicBarrier barrier = new CyclicBarrier(1, new Runnable() { @Override public void run() { System.out.println("barrier" + Thread.currentThread().getName()); } }); public static void main(String[] args) {Thread t1 = new Thread(new Runnable() { @Override public void run() { try { System.out.println("t1 do something"); barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); }} }); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 do something"); try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread t3 = new Thread(new Runnable() { @Override public void run() { System.out.println("t3 do something"); try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); t1.start(); t2.start(); t3.start(); }

信号量分别依次打印ABC,循环10次
public class ABCSemaphore {private static Semaphore A = new Semaphore(1); private static Semaphore B = new Semaphore(1); private static Semaphore C = new Semaphore(1); static class ThreadA extends Thread {@Override public void run() { try { for (int i = 0; i < 10; i++) { A.acquire(); System.out.print("A"); B.release(); } } catch (InterruptedException e) { e.printStackTrace(); } }}static class ThreadB extends Thread {@Override public void run() { try { for (int i = 0; i < 4; i++) { B.acquire(); System.out.print("B"); C.release(); } } catch (InterruptedException e) { e.printStackTrace(); } }}static class ThreadC extends Thread {@Override public void run() { try { for (int i = 0; i < 5; i++) { C.acquire(); System.out.print("C"); A.release(); } } catch (InterruptedException e) { e.printStackTrace(); } }}public static void main(String[] args) throws InterruptedException { // 开始只有A可以获取, BC都不可以获取, 保证了A最先执行 B.acquire(); C.acquire(); new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); } }

放入线程池按照顺序执行线程池中有很多线程去处理任务,不能够保证执行顺序,如果线程池可串行化,那么放入的任务可顺序执行,记得把线程池的线程数设置为1
// 此处注意 线程数设置为1 ExecutorService service = Executors.newFixedThreadPool(1); service.submit(new Runnable() { @Override public void run() { System.out.println("child thread1 do something "); } }); service.submit(new Runnable() { @Override public void run() { System.out.println("child thread2 do something "); } });


    推荐阅读