main函数只执行Thread.activeCount(),打印值为:2

在多线程编程时,作者尝试通过`Thread.activeCount()`来等待所有子线程执行完成。然而,这样做导致了死循环。分析表明,`activeCount`返回的是当前线程组的线程数,包括`main`线程和监控线程。最终,通过调整代码,实现了预期的等待所有子线程完成并输出结果的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写多线程的时候,想要等main中其他线程都执行完成后(其他线程功能为对一个数字inc+1),输出最终的inc值。

于是写了个循环:

while (Thread.activeCount() > 1) {
       System.out.println(Thread.activeCount());
            Thread.yield();
        }
System.out.println(test.inc);

结果进入了死循环

于是,main中只写已下代码:

System.out.println(Thread.activeCount()); // 结果为2

原因如下:

// 获取java线程的管理MXBean
        ThreadMXBean tmxb = ManagementFactory.getThreadMXBean();
        // 不需要获取同步的Monitor和synchronizer信息,仅获取线程和线程堆栈信息
        ThreadInfo[] threadInfos = tmxb.dumpAllThreads(false, false);
        // 遍历线程信息,打印出ID和名称
        for (ThreadInfo info : threadInfos) {
            System.out.println("[" + info.getThreadId() + "] " + info.getThreadName());
        }
[6] Monitor Ctrl-Break
[5] Attach Listener
[4] Signal Dispatcher
[3] Finalizer
[2] Reference Handler
[1] main
System.out.println(Thread.activeCount());
Thread.currentThread().getThreadGroup().list();
2
java.lang.ThreadGroup[name=main,maxpri=10]
    Thread[main,5,main]
    Thread[Monitor Ctrl-Break,5,main]

可以发现当前线程组包含:main和Monitor Ctrl-Break

所有多线程测试代码如下:

### Java 中多线程的使用方法 Java 提供了多种方式来实现多线程编程,主要包括继承 `Thread` 类、实现 `Runnable` 接口以及通过高级并发工具如 `Callable` 和 `FutureTask` 来创建线程。以下是详细的介绍和示例代码。 #### 继承 Thread 类 可以通过继承 `Thread` 类并重写其 `run()` 方法来定义线程的行为[^2]。以下是一个简单示例: ```java public class MyThread extends Thread { @Override public void run() { System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行"); } public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // 启动线程 } } ``` #### 实现 Runnable 接口 另一种更灵活的方式是实现 `Runnable` 接口,并将其传递给 `Thread` 的构造函数[^4]。这种方式允许一个类同时继承其他父类。 ```java class MyRunnable implements Runnable { @Override public void run() { System.out.println("线程 " + Thread.currentThread().getName() + " 正在运行"); } public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); // 启动线程 } } ``` #### 使用 ExecutorService 创建线程池 为了更好地管理线程生命周期,推荐使用 `ExecutorService` 和 `ThreadPoolExecutor` 这样的高级 API[^3]。它们能够有效减少资源消耗并提高性能。 ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5); // 创建固定大小为5的线程池 for (int i = 0; i < 10; i++) { Runnable worker = () -> { try { Thread.sleep(100); System.out.println(Thread.currentThread().getName() + " is running."); } catch (InterruptedException e) { e.printStackTrace(); } }; executor.execute(worker); // 将任务提交到线程池中执行 } executor.shutdown(); // 关闭线程池,不再接受新任务 } } ``` #### 查看当前活跃线程数与 CPU 核心数 可以调用 `Thread.activeCount()` 获取当前 JVM 中活动线程的数量,而 `Runtime.getRuntime().availableProcessors()` 则返回主机上可用处理器的核心数目[^1]。 ```java public class ActiveThreadsAndCPUs { public static void main(String[] args) { System.out.println("当前活跃线程数:" + Thread.activeCount()); System.out.println("可用处理器核心数:" + Runtime.getRuntime().availableProcessors()); } } ``` #### 高级同步机制 CyclicBarrier 和 CountDownLatch 对于需要多个线程协作完成的任务场景,可考虑采用 `CyclicBarrier` 或者 `CountDownLatch` 工具类。前者用于等待一组线程到达某个屏障后再继续;后者则是在计数降为零时释放所有等待中的线程。 ```java // CyclicBarrier 示例 import java.util.concurrent.BARRIER; public class BarrierDemo { public static void main(String[] args) throws Exception { BARRIER barrier = new BARRIER(2); Thread t1 = new Thread(() -> { try { System.out.println("线程A已准备好..."); barrier.await(); System.out.println("线程A开始工作!"); } catch (Exception ex) {} }); Thread t2 = new Thread(() -> { try { System.out.println("线程B已准备好..."); barrier.await(); System.out.println("线程B开始工作!"); } catch (Exception ex) {} }); t1.start(); t2.start(); t1.join(); t2.join(); } } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值