时人不识凌云木,直待凌云始道高。这篇文章主要讲述面试官:你说说如何让“线程”按序执行?相关的知识,希望能为你提供帮助。
【面试官(你说说如何让“线程”按序执行())】当线程处于就绪状态时,等待被分配到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 ");
}
});
推荐阅读
- 一次ISV诉求引出的SQL优化步骤的分享
- Java虚拟机规范JVM类加载机制
- 「推荐收藏!」MySQL技术之旅「主从架构」MySQL主从数据同步模式的指南分析
- VMware产品介绍
- 一起玩转树莓派(15)——干簧管传感器
- 史上最全jdk新特性总结,涵盖jdk8到jdk15!
- 走进Java接口测试之从0到1搭建数据驱动框架(需求篇)
- 浅谈 Xamarin Community Toolkit 的未来发展
- 海量数字化业务时代,企业应用发布自动化系统应该如何设计()