直接继承thread类无法控制并发数量,必须借助semaphore或线程池等协调机制;推荐使用固定大小的executorservice调度任务,而非手动start()线程。

直接继承 Thread 类本身不提供内置的并发数量控制能力。它只是封装了一个线程执行单元,每次调用 start() 就会创建并启动一个新线程——这恰恰是容易导致并发失控的根源。所以,不能靠“继承 Thread 类”这一步来限制并发数;真正起作用的是后续引入的协调机制。
要实现限制并发数量,必须在 Thread 子类的运行逻辑中,配合外部资源协调工具或统一调度层。以下是两种切实可行、符合实际工程场景的做法:
使用 Semaphore 控制并发入口
适用于需要精确控制“同时运行的线程数”,且任务逻辑已封装在 Thread 子类中:
- 创建一个静态
Semaphore,设定许可数量(如 3); - 在
run()方法开头调用acquire(),阻塞直到获得许可; - 执行业务逻辑(比如模拟耗时操作);
- 最后在
finally块中调用release(),归还许可。
import java.util.concurrent.Semaphore;
class LimitedThread extends Thread {
private static final Semaphore semaphore = new Semaphore(3); // 最多3个并发
@Override
public void run() {
try {
semaphore.acquire(); // 等待许可
System.out.println(getName() + " 开始执行");
Thread.sleep(1000);
System.out.println(getName() + " 执行完成");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release(); // 释放许可
}
}
}
// 启动10个线程,但最多3个同时运行
public class Main {
public static void main(String[] args) {
for (int i = 0; i <h3>改用 Thread + 外部线程池调度(推荐)</h3><p>更合理的方式是:把任务逻辑写成 <code>Thread</code> 子类(或 <code>Runnable</code>),但<strong>不直接 start(),而是提交给固定大小的线程池</strong>:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7672" title="java-enterprise"><img
src="https://img.php.cn/upload/skill/000/000/081/179161929545163.jpg" alt="java-enterprise" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill7672" title="java-enterprise" class="overflowclass">java-enterprise</a>
<p class="overflowclass">Java企业开发专家,专注于Spring Boot、微服务架构和JVM优化。适用于:Java语言掌握、</p>
</div>
<a rel="nofollow" href="/xiazai/skill7672" title="java-enterprise" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
-
LimitedThread仍可存在,只负责定义行为; - 实际启动交给
ExecutorService,由它决定何时、用哪个线程执行; - 这样既保留了自定义线程逻辑的灵活性,又把并发控制权交给成熟组件。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class LimitedThread extends Thread {
private final String taskName;
LimitedThread(String name) {
this.taskName = name;
}
@Override
public void run() {
System.out.println(taskName + " 开始(线程:" + Thread.currentThread().getName() + ")");
try { Thread.sleep(800); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
System.out.println(taskName + " 完成");
}
}
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(4); // 严格限制为4个并发
for (int i = 0; i new LimitedThread("Task-" + id).run());
}
pool.shutdown();
}
}
不推荐的做法:手动计数 + synchronized
例如用静态变量 runningCount 加锁增减——容易出错、难维护、无法应对中断和异常退出,且不具备公平性与阻塞等待能力,生产环境应避免。
本质上,并发数量控制属于资源协调问题,不是线程创建方式的问题。继承 Thread 是一种低层抽象,而限流、排队、复用等能力,应由 Semaphore、ExecutorService 或 ThreadPoolExecutor 这类高层工具承担。
不复杂但容易忽略:限制并发的关键不在“怎么建线程”,而在“谁来管它们一起跑”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










