【Java多线程系列四】控制线程执行顺序

java

假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现

  • Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕
  • CountDownLatch类:指定计数器,当计数器清零即取消阻塞

package com.concurrent.test;

import java.util.concurrent.CountDownLatch;

import org.junit.Assert;

import org.junit.Test;

/**

* 规定线程的执行顺序

*/

public class ThreadOrderTest {

private long millisUnit = 1000;

private int count = 2;

class ThreadOrder {

/*

* join方法使多个线程依次执行

*/

public long preserveOrderViaJoin() throws InterruptedException {

long startMillis = System.currentTimeMillis();

Thread tmp;

for (int i = 0; i < count; i++) {

tmp = new Thread(new Runnable() {

@Override

public void run() {

try {

Thread.sleep(millisUnit);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}, "join-" + i);

tmp.start();

tmp.join();//不停地监测线程是否执行完成,执行完成才继续往下

}

return System.currentTimeMillis() - startMillis;

}

/*

* CountdownLatch可同时阻塞多个线程,但它们可并发执行

*/

public long preserveOrderViaCountdownLatch() throws InterruptedException {

long startMillis = System.currentTimeMillis();

final CountDownLatch countDownLatch = new CountDownLatch(count);

for (int i = 0; i < count; i++) {

new Thread(new Runnable() {

@Override

public void run() {

try {

Thread.sleep(millisUnit);

} catch (InterruptedException e) {

e.printStackTrace();

}

//只要计数器清零,等待的线程就可以开始执行,于是可以达到并发的效果

countDownLatch.countDown();

}

},"countDownLatch-" + i).start();

}

countDownLatch.await();

return System.currentTimeMillis() - startMillis;

}

}

@Test

public void testPreserveOrderViaJoin() throws InterruptedException {

ThreadOrder threadOrder = new ThreadOrder();

Assert.assertEquals(count, threadOrder.preserveOrderViaJoin() / millisUnit);

}

@Test

public void testPreserveOrderViaCountdownLatch() throws InterruptedException {

ThreadOrder threadOrder = new ThreadOrder();

Assert.assertEquals(1, threadOrder.preserveOrderViaCountdownLatch() / millisUnit);

}

}

以上是 【Java多线程系列四】控制线程执行顺序 的全部内容, 来源链接: utcz.com/z/392728.html

回到顶部