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

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


                
<think>我们使用MyBatis-Plus的LambdaQueryWrapper进行查询时,如果实体类中有字段标记了`@TableLogic`(逻辑删除注解),那么默认情况下,MP会自动在查询语句中拼接`del_flag=0`的条件(这里的0是代表未删除的,具体由注解配置决定)。这会导致我们无法查询到已删除(`del_flag=1`)的数据。为了查询到所有数据(包括已删除和未删除),我们需要在LambdaQueryWrapper上调用`ignoreLogic()`方法,这样MP就不会自动添加逻辑删除条件。下面通过代码示例说明:###使用LambdaQueryWrapper查询所有数据(忽略逻辑删除条件)```java//创建LambdaQueryWrapper,并调用ignoreLogic()方法LambdaQueryWrapper<User>wrapper=newLambdaQueryWrapper<>();wrapper.ignoreLogic();//关键:忽略逻辑删除条件//可以继续添加其他查询条件wrapper.eq(User::getName,"John");//或者指定查询某些字段wrapper.select(User::getId,User::getName);//执行查询List<User>users=userMapper.selectList(wrapper);```###代码说明:1.**`wrapper.ignoreLogic()`**:这是关键的一步,它告诉MP不要自动添加逻辑删除条件(即`del_flag=0`),这样查询就会包含所有状态的数据(包括已删除和未删除)。2.**其他条件**:在忽略逻辑删除条件后,你可以像往常一样添加其他查询条件(如eq,like等)。3.**查询结果**:返回的列表将包含所有满足条件的记录,无论它们的`del_flag`是0还是1。###注意事项:-如果实体类中没有使用`@TableLogic`注解,那么不会自动添加逻辑删除条件,也就不需要调用`ignoreLogic()`。-使用`ignoreLogic()`后,如果你需要根据`del_flag`进行筛选,可以手动添加条件。例如,你只想查询已删除的数据:```javawrapper.eq(User::getDelFlag,1);```或者同时查询已删除和未删除:```javawrapper.in(User::getDelFlag,Arrays.asList(0,1));```-注意:忽略逻辑删除后,查询可能会包含大量已删除的数据,请确保这是你需要的,并考虑性能问题(如分页查询)。###代码Review正确性:-确保你的实体类中有逻辑删除字段,并用`@TableLogic`注解标注。例如:```java@TableLogic(value="0",delval="1")//未删除为0,删除为1privateIntegerdelFlag;```-在调用`ignoreLogic()`后,检查是否真的在SQL中去掉了逻辑删除条件(可以通过控制台输出SQL语句来验证)。-如果你使用的是MyBatis-Plus版本低于3.3.0,请检查是否支持`ignoreLogic()`方法(该方法在3.3.0及以上版本中可用)。###替代方法:自定义SQL如果由于版本原因无法使用`ignoreLogic()`,或者你需要更复杂的查询,可以考虑自定义SQL语句(在Mapper接口中定义方法,并使用注解或XML编写SQL),这样就不会受到MP自动逻辑删除条件的影响。例如:```java@Select("SELECT*FROMuserWHEREname=#{name}")//这里不会自动添加del_flag条件List<User>selectAllByName(@Param("name")Stringname);```###总结:使用`LambdaQueryWrapper.ignoreLogic()`可以方便地避免自动拼接逻辑删除条件,从而使查询能够获取到已删除和未删除的数据。在使用前请确保你的MP版本支持该方法,并注意查询结果中可能包含已删除数据的影响。§§相关问题§§1.MyBatis-Plus中逻辑删除的配置和原理是什么?2.如何在MyBatis-Plus中只查询已被逻辑删除的数据?3.使用`ignoreLogic()`后,对更新和删除操作会有什么影响?</think> ### 使用LambdaQueryWrapper查询所有数据(包含已删除/未删除)的正确方式 在MyBatis-Plus中使用`LambdaQueryWrapper`查询所有数据(含已删除和未删除数据)的关键是调用`ignoreLogic()`方法。下面是详细步骤和代码验证: #### 正确代码示例 ```java // 1. 创建LambdaQueryWrapper LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>(); // 2. 关键步骤:忽略逻辑删除自动过滤 lambdaWrapper.ignoreLogic(); // 3. 可选:添加其他查询条件 lambdaWrapper.eq(User::getName, "John") .ge(User::getCreateTime, LocalDate.now().minusMonths(1)); // 4. 执行查询(包含所有状态的记录) List<User> allUsers = userMapper.selectList(lambdaWrapper); ``` #### 代码验证要点 1. **SQL生成验证**: ```sql SELECT * FROM user WHERE name = 'John' AND create_time >= '2023-12-01' /* 无 del_flag=0 条件 */ ``` 2. **实体类逻辑删除配置**: ```java @Data public class User { @TableLogic(value = "0", delval = "1") // 未删除=0,已删除=1 private Integer delFlag; // 其他字段... } ``` 3. **数据验证方法**: ```java // 检查结果集是否包含两种状态的数据 long deletedCount = allUsers.stream() .filter(u -> u.getDelFlag() == 1) .count(); long activeCount = allUsers.stream() .filter(u -> u.getDelFlag() == 0) .count(); assert deletedCount > 0 && activeCount > 0 : "查询应包含两种状态数据"; ``` #### 常见问题解决 1. **查询结果缺少已删除数据**: - ✅ 确保调用了 `ignoreLogic()` - ✅ 检查实体类 `@TableLogic` 的 `delval` 是否正确 - ✅ 数据库确认存在 `del_flag=1` 的记录 2. **新版MP兼容性**(3.4.0+): ```java // 替代方案:使用withoutLogic()方法 lambdaWrapper.withoutLogic(); ``` #### 特殊场景处理 **分页查询所有状态数据**: ```java Page<User> page = new Page<>(1, 10); LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.ignoreLogic(); Page<User> result = userMapper.selectPage(page, wrapper); // 验证分页结果 assert result.getRecords().size() > 0; assert result.getTotal() == databaseTotalCount; // 包含所有状态的总数 ``` #### 核心原理说明 当调用 `ignoreLogic()` 时,MyBatis-Plus 会: 1. 禁用 `SqlParser` 的逻辑删除过滤器 2. 跳过 `AbstractWrapper` 的自动条件注入 3. 保留其他查询条件的正常拼接 > ⚠️ **注意**:更新/删除操作仍受 `@TableLogic` 约束,只有查询操作可通过此方式绕过逻辑删除过滤[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值