[Thread] 多线程顺序执行
Join
主线程join
启动线程t1,随后调用join,main线程需要等t1线程执行完毕后继续执行。
public class MainJoin {
static class MyThread implements Runnable {
String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + "开始执行");
try {
//todo 业务逻辑
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "执行完毕");
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new MyThread("第一个线程"));
Thread t2 = new Thread(new MyThread("第二个线程"));
Thread t3 = new Thread(new MyThread("第三个线程"));
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
}
}
线程池写法
public class ThreadPool {
private static final ExecutorService executorService = new ThreadPoolExecutor(1, 1, 0L
, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()
, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
static class MyThread implements Runnable {
String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + "开始执行");
try {
//todo 执行业务逻辑
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "执行完毕");
}
}
public static void main(String[] args) {
executorService.submit(new MyThread("第一个线程"));
executorService.submit(new MyThread("第二个线程"));
executorService.submit(new MyThread("第三个线程"));
executorService.shutdown();
}
}
wait notify
这里的原理就是线程t1、t2共用一把锁myLock1,t2先wait阻塞,等待t1执行完毕notify通知t2继续往下执行,线程t2、t3共用一把锁myLock2,t3先wait阻塞,等待t2执行完毕notify通知t3继续往下执行。
public class WaitNotify {
private static Object myLock1 = new Object();
private static Object myLock2 = new Object();
static class MyThread implements Runnable {
String name;
Object startLock;
Object endLock;
public MyThread(String name, Object startLock, Object endLock) {
this.name = name;
this.startLock = startLock;
this.endLock = endLock;
}
@Override
public void run() {
if (startLock != null) {
synchronized (startLock) {
//阻塞
try {
startLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//继续往下执行
System.out.println(name + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (endLock != null) {
synchronized (endLock) {
//唤醒
endLock.notify();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread("第一个线程", null, myLock1));
Thread t2 = new Thread(new MyThread("第二个线程", myLock1, myLock2));
Thread t3 = new Thread(new MyThread("第三个线程", myLock2, null));
//打乱顺序执行
t3.start();
t1.start();
t2.start();
}
}
Condition
类似 wait notify
public class ConditionDemo {
private static Lock lock = new ReentrantLock();
private static Condition condition1 = lock.newCondition();
private static Condition condition2 = lock.newCondition();
static class MyThread implements Runnable {
String name;
Condition startCondition;
Condition endCondition;
public MyThread(String name, Condition startCondition, Condition endCondition) {
this.name = name;
this.startCondition = startCondition;
this.endCondition = endCondition;
}
@Override
public void run() {
//阻塞
if (startCondition != null) {
lock.lock();
try {
startCondition.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//继续往下执行
System.out.println(name + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//唤醒
if (endCondition != null) {
lock.lock();
try {
endCondition.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread("第一个线程", null, condition1));
Thread t2 = new Thread(new MyThread("第二个线程", condition1, condition2));
Thread t3 = new Thread(new MyThread("第三个线程", condition2, null));
//打乱顺序执行
t3.start();
t2.start();
t1.start();
}
}
CountDownLatch
public class CountDownLatchDemo {
static class MyThread implements Runnable {
CountDownLatch startCountDown;
CountDownLatch endCountDown;
public MyThread(CountDownLatch startCountDown, CountDownLatch endCountDown) {
this.startCountDown = startCountDown;
this.endCountDown = endCountDown;
}
@Override
public void run() {
//阻塞
if (startCountDown != null) {
try {
startCountDown.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//执行自己的业务逻辑
System.out.println(Thread.currentThread().getName() + "开始执行");
//todo 执行业务逻辑
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (endCountDown != null) {
endCountDown.countDown();
}
}
}
public static void main(String[] args) {
CountDownLatch countDownLatch1 = new CountDownLatch(1);
CountDownLatch countDownLatch2 = new CountDownLatch(1);
Thread t1 = new Thread(new MyThread(null, countDownLatch1), "第一个线程");
Thread t2 = new Thread(new MyThread(countDownLatch1, countDownLatch2), "第二个线程");
Thread t3 = new Thread(new MyThread(countDownLatch2, null), "第三个线程");
//打乱顺序执行
t3.start();
t2.start();
t1.start();
}
}
等待多线程完成的CountDownLatch
public static void main(String[] args) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(5);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线程执行");
latch.countDown();
}).start();
}
latch.await();
System.out.println("主线程执行");
}
CompletableFutureDemo
public class CompletableFutureDemo {
static class MyThread implements Runnable {
@Override
public void run() {
System.out.println("执行 : " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread(), "线程1");
Thread t2 = new Thread(new MyThread(), "线程2");
Thread t3 = new Thread(new MyThread(), "线程3");
CompletableFuture.runAsync(t1::start).thenRun(t2::start).thenRun(t3::start);
}
}