线程类的join()方法
t2线程使用了t1.join(),表示只有t1线程执行完毕以后,再执行该t2线程,t3线程同理。这样就实现了t1在t2之前,t2在t3之前执行的顺序执行。
public class JoinTest {
public static void main(String[] args) {
// 创建线程对象
Thread t1 = new Thread(() -> {
System.out.println("t1");
}) ;
Thread t2 = new Thread(() -> {
try {
t1.join(); // 加入线程t1,只有t1线程执行完毕以后,再次执行该线程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
}) ;
Thread t3 = new Thread(() -> {
try {
t2.join(); // 加入线程t2,只有t2线程执行完毕以后,再次执行该线程
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
}) ;
// 启动线程
t3.start();
t2.start();
t1.start();
}
}
使用CountDownLatch
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
// 创建CountDownLatch对象
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
CountDownLatch latch3 = new CountDownLatch(1);
Thread t1 = new Thread(() -> {
System.out.println("t1");
latch1.countDown(); // 执行完毕后,计数器减1
});
// 启动线程
t1.start();
latch1.await();
Thread t2 = new Thread(() -> {
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
latch2.countDown(); // 执行完毕后,计数器减1
});
// 启动线程
t2.start();
latch2.await();
Thread t3 = new Thread(() -> {
try {
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
latch3.countDown(); // 执行完毕后,计数器减1
});
// 启动线程
t3.start();
latch3.await();
}
}
使用 CyclicBarrier
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1 = new Thread(() -> {
System.out.println("t1");
try {
// 到达此屏障,等待其他线程
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
});
// 启动线程
t1.start();
// 等待线程1执行完
barrier.await();
Thread t2 = new Thread(() -> {
try {
barrier.await();
System.out.println("t2");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
});
// 启动线程
t2.start();
// 等待线程2执行完
barrier.await();
Thread t3 = new Thread(() -> {
try {
barrier.await();
System.out.println("t3");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
});
// 启动线程
t3.start();
// 等待线程3执行完
barrier.await();
}
}
使用Semaphore
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
private static Semaphore semaphore = new Semaphore(1);
public static void main(String[] args) {
semaphore.acquire(); // 获取permit
Thread t1 = new Thread(() -> {
try {
System.out.println("t1");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放permit,允许t2执行
}
});
t1.start();
semaphore.acquire(); // 获取permit
Thread t2 = new Thread(() -> {
try {
System.out.println("t2");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore3.release(); // 释放permit,允许t3执行
}
});
t2.start();
semaphore.acquire(); // 获取permit
Thread t3 = new Thread(() -> {
try {
semaphore3.acquire(); // 获取permit
System.out.println("t3");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore1.release(); // 释放permit,允许t1执行
}
});
t3.start();
}
}
使用单个线程的线程池
使用异步回调类类CompletableFuture
CompletableFuture.runAsync()方法用于异步执行新的线程,thenRun()方法用于在当前任务正常完成后执行给定的动作。join()方法用于等待所有任务完成。这样就可以保证t1、t2、t3线程的顺序执行。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureTest {
public static void main(String[] args) {
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
System.out.println("t1");
});
CompletableFuture<Void> future2 = future1.thenRun(() -> {
System.out.println("t2");
});
CompletableFuture<Void> future3 = future2.thenRun(() -> {
System.out.println("t3");
});
// 等待所有任务完成
future3.join();
}
}