最近在网上看到一篇关于多线程的面试题,平时虽然有看过一些并发的理论,但是实际编码较少,因此也是特意练习一下。
题目描述:
怎么让线程A、线程B、线程C顺序执行?
方案一:利用线程的join()方法,join()方法是线程类的实例方法,其作用是在当前线程中调用目标线程的join()方法,则当前线程进入Waiting状态,目标线程执行完毕后当前线程才再次进入Runable状态。
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new ThreadA());
Thread t2 = new Thread(new ThreadB(t1));
Thread t3 = new Thread(new ThreadC(t2));
t1.start();
t2.start();
t3.start();
}
static class ThreadA implements Runnable {
@Override
public void run() {
System.out.println("ThreadA");
}
}
static class ThreadB implements Runnable{
private Thread thread;
public ThreadB(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
try {
//目标线程先执行完才继续执行此线程执行体
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB");
}
}
static class ThreadC implements Runnable {
private Thread thread;
public ThreadC(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
try {
//目标线程先执行完才继续执行此线程执行体
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadC");
}
}
}
方案二:借助线程池技术,newSingleThreadExecutor保证了其内只有一个线程在执行,且提交的线程执行体是按照FIFO的顺序执行的。
public class ExecutorServiceDemo {
public static void main(String[] args) {
ExecutorService executorPool = Executors.newSingleThreadExecutor();
executorPool.submit(new ThreadA());
executorPool.submit(new ThreadB());
executorPool.submit(new ThreadC());
}
static class ThreadA implements Runnable {
@Override
public void run() {
System.out.println("ThreadA");
}
}
static class ThreadB implements Runnable{
@Override
public void run() {
System.out.println("ThreadB");
}
}
static class ThreadC implements Runnable {
@Override
public void run() {
System.out.println("ThreadC");
}
}
}
怎么保证多个线程按顺序循环执行一段代码?
借鉴网上一种优雅的解决方案,但是原文的代码我认为有点问题,因为它对线程内部的代码加锁对于其他线程来说是无效的。
原文链接:https://blog.csdn.net/feng15230805625/article/details/83350724
但是其思路是可以借鉴的,它利用锁机制来实现对一个共享变量的互斥访问,然后当这个共享变量等于特定值时执行特定的线程。下面是我的代码:
对于add()方法,同一时间只能有一个线程执行它,然后在其内部持有一个计数器count,每次执行add()方法后修改计数器保证下一个线程执行add()方法。
public class CycleDemo {
private static Integer count = 0;
private synchronized static void add() {
System.out.println(Thread.currentThread().getName());
count++;
}
private static Integer get() {
return count;
}
static class ThreadA implements Runnable {
@Override
public void run() {
Thread.currentThread().setName("ThreadA");
while (true) {
if(get() % 3 == 0 && get() < 999) {
add(); //它保证了线程B在其后执行
}
}
}
}
static class ThreadB implements Runnable {
@Override
public void run() {
Thread.currentThread().setName("ThreadB");
while (true) {
if(get() % 3 == 1 && get() < 999) {
add();
}
}
}
}
static class ThreadC implements Runnable {
@Override
public void run() {
Thread.currentThread().setName("ThreadC");
while (true) {
if(get() % 3 == 2 && get() < 999) {
add();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new ThreadA());
Thread t2 = new Thread(new ThreadB());
Thread t3 = new Thread(new ThreadC());
t3.start();
t2.start();
t1.start();
}
}