异步执行之线程之间顺序执行方案
主线程等待子线程的终止。也就是说主线程的代码块中,如果碰到了t.join()方法,此时主线程需要等待(阻塞),等待子线程结束了(Waits for this thread to die.),才能继续执行t.join()之后的代码块。join()的使用场景:在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程将可能早于子线程结束。如果主线程需要知道子线程的执行结果时,就需要
·
方案一: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)