多个线程顺序执行
日常总结都在github,大家可以看一下: https://github.com/nocoders/java-everything.git,本文示例代码在src.main.test.com.javaEverything.java.concurrent
目录下
今天面试遇到这个问题,A、B、C三个线程,如何让他们按照顺序执行。当时没想起来怎么说,后来百度了下,发现实现有好几种方式,可以使用Thread.join()
、使用ReentrantLock
、使用Semaphore
。
Thread.join()
Thread.join()
:阻塞当前线程,直到执行线程执行结束。
定义三个线程,A线程直接start,B线程要等A线程执行结束才能执行,C线程要等A B线程执行结束才能执行。
示例代码
@Test
public void threadSortJoin() {
Thread A = new Thread(() -> {
System.out.println("Thread A run");
});
Thread B = new Thread(() -> {
try {
A.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread B run");
});
Thread C = new Thread(() -> {
try {
A.join();
B.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread C run");
});
A.start();
B.start();
C.start();
}
Semaphore
Semaphore
相关见参考链接2,给线程B、C定义两个信号量为0的Semaphore,A线程中执行完毕释放B线程对应的信号量,B线程执行完毕释放C线程的信号量。
示例代码
@Test
public void threadSortSemaphore() {
Semaphore sb = new Semaphore(0);
Semaphore sc = new Semaphore(0);
Thread A = new Thread(()->{
System.out.println("Thread A run");
sb.release();
});
Thread B = new Thread(()->{
try {
sb.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread B run");
sc.release();
});
Thread C = new Thread(() -> {
try {
sc.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread C run");
});
A.start();
B.start();
C.start();
}
ReentrantLock
定义一个number指定线程执行顺序,定义三个condition,number等于几,唤醒第几个线程执行。
@Test
public void threadSortReentrantLock() {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
AtomicInteger number = new AtomicInteger(1);
Thread A = new Thread(() -> {
System.out.println(1);
lock.lock();
try {
while (number.get() != 1) {
conditionA.await();
}
System.out.println("Thread A run");
number.set(2);
conditionB.signal();
} catch (Exception e) {
} finally {
lock.unlock();
}
});
Thread B = new Thread(() -> {
System.out.println(2);
lock.lock();
try {
while (number.get() != 2) {
conditionB.await();
}
System.out.println("Thread B run");
number.set(3);
conditionC.signal();
} catch (Exception e) {
} finally {
lock.unlock();
}
});
Thread C = new Thread(() -> {
System.out.println(3);
while (number.get()!=2){
}
lock.lock();
try {
while (number.get() != 3) {
conditionC.await();
}
System.out.println("Thread C run");
number.set(1);
conditionA.signal();
} catch (Exception e) {
}finally {
lock.unlock();
}
});
A.start();
B.start();
C.start();
}
参考链接
- 多线程中Thread的join方法
- Semaphore 使用及原理
- JAVA实现多个线程顺序执行的几种方式
- [让线程按顺序执行8种方法](