You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CountDownLatch设计单跑道航班调度的代码问题排查求助

单跑道航班调度代码问题排查与修正

核心问题分析

你用CountDownLatch实现互斥完全搞错了它的用途:

  • CountDownLatch是一次性组件:计数器减到0后,所有等待的线程都会被唤醒,但计数器不会再恢复,后续调用countDown()也无法让它回到初始值。
  • 你的代码里初始计数设为1,所有线程调用latch.await()后都会永久阻塞——因为没有任何线程先调用countDown()把计数器降到0,程序直接卡死。

正确实现方案

单跑道互斥的本质是同一时刻仅允许一个线程访问资源,适合用Semaphore(信号量,许可数设为1)或ReentrantLock实现。以下是用Semaphore修正后的代码:

import java.util.concurrent.Semaphore;

public class LandingArrivingFlights {
    private static final int NUM_FLIGHTS = 5;
    private static final int RUNWAY_CAPACITY = 1;

    public static void main(String[] args) {
        // 信号量设置1个许可,实现互斥访问
        Semaphore runwaySemaphore = new Semaphore(RUNWAY_CAPACITY);

        for (int i = 0; i < NUM_FLIGHTS; i++) {
            Flight flight = new Flight(i + 1, runwaySemaphore);
            new Thread(flight).start();
        }
    }

    private static class Flight implements Runnable {
        private int flightNum;
        private Semaphore runwaySemaphore;

        public Flight(int flightNum, Semaphore runwaySemaphore) {
            this.flightNum = flightNum;
            this.runwaySemaphore = runwaySemaphore;
        }

        public void run() {
            try {
                // 获取跑道许可,无许可则等待
                runwaySemaphore.acquire();

                // 模拟航班起降操作
                if (flightNum % 2 == 0) {
                    System.out.println("Flight " + flightNum + " is taking off.");
                } else {
                    System.out.println("Flight " + flightNum + " is landing.");
                }
                // 模拟实际起降耗时,让调度效果更直观
                Thread.sleep(1000);

                // 释放跑道许可,供其他航班使用
                runwaySemaphore.release();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                e.printStackTrace();
            }
        }
    }
}

关键说明

  • Semaphore的acquire()方法会尝试获取许可,无可用许可时线程阻塞;release()会释放许可,唤醒等待队列中的线程。
  • 新增Thread.sleep(1000)模拟实际起降的耗时,能清晰看到同一时刻只有一个航班在使用跑道。
  • 将内部类名从Runway改为Flight,更符合线程代表航班的语义。

内容的提问来源于stack exchange,提问作者Karthikeyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:43:36