异步执行之线程之间顺序执行方案
·
方案一:join
主线程等待子线程的终止。也就是说主线程的代码块中,如果碰到了t.join()方法,此时主线程需要等待(阻塞),等待子线程结束了(Waits for this thread to die.),才能继续执行t.join()之后的代码块。
join()的使用场景:
在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将可能早于子线程结束。如果主线程需要知道子线程的执行结果时,就需要等待子线程执行结束了。主线程可以sleep(xx),但这样的xx时间不好确定,因为子线程的执行时间不确定,join()方法比较合适这个场景。
join() 和 sleep() 一样,可以被中断(被中断时,会抛出 InterrupptedException 异常);不同的是,join() 内部调用了 wait(),会出让锁,而 sleep() 会一直保持锁。
public class ThreadSequence {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> System.out.println("线程1执行"));
Thread t2 = new Thread(() -> System.out.println("线程2执行"));
Thread t3 = new Thread(() -> System.out.println("线程3执行"));
t1.start();
t1.join(); // 等待t1执行完成
t2.start();
t2.join(); // 等待t2执行完成
t3.start();
t3.join(); // 等待t3执行完成
}
}
方案二:CountDownLatch
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) {
CountDownLatch latch1 = new CountDownLatch(1);
CountDownLatch latch2 = new CountDownLatch(1);
Thread t1 = new Thread(() -> {
System.out.println("线程1执行");
latch1.countDown();
});
Thread t2 = new Thread(() -> {
try {
latch1.await(); // 等待线程1完成
System.out.println("线程2执行");
latch2.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
latch2.await(); // 等待线程2完成
System.out.println("线程3执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
方案三:信号量semaphore
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private static Semaphore semaphore1 = new Semaphore(1);
private static Semaphore semaphore2 = new Semaphore(0);
private static Semaphore semaphore3 = new Semaphore(0);
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
try {
semaphore1.acquire();
System.out.println("线程1执行");
semaphore2.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
semaphore2.acquire();
System.out.println("线程2执行");
semaphore3.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
semaphore3.acquire();
System.out.println("线程3执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
}
}
方案四:synchronized + wait/notify
public class WaitNotifyExample {
private static Object lock = new Object();
private static int count = 1;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (lock) {
while (count != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程1执行");
count = 2;
lock.notifyAll();
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
while (count != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程2执行");
count = 3;
lock.notifyAll();
}
});
Thread t3 = new Thread(() -> {
synchronized (lock) {
while (count != 3) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程3执行");
}
});
t1.start();
t2.start();
t3.start();
}
}
方案五:使用线程池 + Future
import java.util.concurrent.*;
public class ExecutorServiceExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(3);
Future<?> future1 = executor.submit(() -> System.out.println("线程1执行"));
future1.get(); // 等待线程1完成
Future<?> future2 = executor.submit(() -> System.out.println("线程2执行"));
future2.get(); // 等待线程2完成
Future<?> future3 = executor.submit(() -> System.out.println("线程3执行"));
future3.get(); // 等待线程3完成
executor.shutdown();
}
}
方案六: CompletableFuture
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.runAsync(() -> System.out.println("线程1执行"))
.thenRun(() -> System.out.println("线程2执行"))
.thenRun(() -> System.out.println("线程3执行"))
.join();
}
}
更多推荐

所有评论(0)