日常总结都在github,大家可以看一下: https://github.com/nocoders/java-everything.git,本文示例代码在src.main.test.com.javaEverything.java.concurrent
目录下
今天面试遇到这个问题,A、B、C三个线程,如何让他们按照顺序执行。当时没想起来怎么说,后来百度了下,发现实现有好几种方式,可以使用Thread.join()
、使用ReentrantLock
、使用Semaphore
。
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
相关见参考链接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();
}
定义一个number指定线程执行顺序,定义三个condition,number等于几,唤醒第几个线程执行。
@Testpublic 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();}