在项目中,发现Spring的定时任务中用ThreadLocal来保存上下文信息,且上下文信息中有一个属性在后面入库时是做为主键值。总觉得这里应该有问题,因为没有去看过Spring的定时任务的具体实现,也不知定时任务用没用线程池以及如何使用的,但如何用了线程池(且我觉得从性能和常理推测来看应该是要用的),用ThreadLocal保存上下文信息,并在后续使用(且使用完没有做remove),那么后面就一定会出现主键冲突呀。
为了偷懒,也为了尽快验证我的推断,写了一个很简单的测试代码如下。
为了偷懒,也为了尽快验证我的推断,写了一个很简单的测试代码如下。
Context.java
package com.bijian.study.dto; public class Context { private int seqNo; public int getSeqNo() { return seqNo; } public void setSeqNo(int seqNo) { this.seqNo = seqNo; } }
HelloService.java
package com.bijian.study.service; public interface HelloService { public String processService(String name) throws Exception; public String processService() throws Exception; }
HelloServiceImpl.java
package com.bijian.study.service.impl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import com.bijian.study.dto.Context; import com.bijian.study.service.HelloService; import com.bijian.study.util.ContextThreadLocal; @Service("helloService") public class HelloServiceImpl implements HelloService { private static Logger logger = LoggerFactory.getLogger(HelloServiceImpl.class); private static int count; @Override public String processService(String name) throws Exception { logger.info("HelloService processService name:" + name); return "Hello " + name; } @Override public String processService() throws Exception { Context context = ContextThreadLocal.get(); if(context == null) { count++; context = new Context(); context.setSeqNo(count); ContextThreadLocal.set(context); } logger.info("HelloService processService seqNo:" + context.getSeqNo()); return "Hello " + context.getSeqNo(); } }
ContextThreadLocal.java
package com.bijian.study.util; import com.bijian.study.dto.Context; public class ContextThreadLocal { public static final ThreadLocal<Context> userContextThreadLocal = new ThreadLocal<Context>(); public static void set(Context userContext) { userContextThreadLocal.set(userContext); } public static void unset() { userContextThreadLocal.remove(); } public static Context get() { return userContextThreadLocal.get(); } }
springMVC-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"> <context:component-scan base-package="com.bijian.study"></context:component-scan> <context:annotation-config /> <mvc:annotation-driven></mvc:annotation-driven> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views" /> <property name="suffix" value=".jsp" /> </bean> <task:scheduled-tasks> <task:scheduled ref="helloService" method="processService" initial-delay="5000" fixed-delay="1"/> </task:scheduled-tasks> </beans>
运行结果:
从运行结果来看,Spring定时任务肯定用到了线程,且在上面这种运用场景是肯定会出现主键冲突。当然,这里的解决办法也很简单,即在使用完ThreadLocal中的上下文信息后,做remove的清理动作。
相关推荐
可以在测试类中使用`@TestPropertySource`来模拟不同的时间环境,以便在单元测试中正确触发定时任务。 以上就是Spring Boot整合定时任务的相关知识点,通过这些知识,我们可以灵活地构建和管理应用中的定时任务,...
在Spring框架中集成Quartz,可以利用Spring的强大功能来管理Quartz的bean,实现更高效和稳定的定时任务调度。 1. **Quartz基础概念** - **Job**:Quartz中的任务单元,代表要执行的具体业务逻辑。 - **Trigger**...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...
在企业级应用开发中,经常会遇到需要从多个数据库拉取数据的情况,比如进行跨库查询、定时任务中的数据分析及报表统计等。Spring框架作为Java开发领域的主流框架之一,提供了丰富的API和配置选项,使得开发者能够...
4. 定时任务:Quartz或Spring Task用于安排定期任务,如用户提醒、数据分析等。 5. 分布式任务调度:如使用Apache Kafka、RabbitMQ等消息队列进行任务分发,减轻单点压力。 6. 线程池:Java的ExecutorService允许...
- 在Spring框架中,ThreadLocal被广泛应用于管理Request作用域中的Bean、事务管理、任务调度、AOP等方面。 #### Synchronized与Lock - **Synchronized**:关键字synchronized是Java内置的关键字,用于实现线程...
实现线程安全的方法包括:synchronized关键字(提供互斥访问)、 volatile(保证可见性,防止指令重排序)、ThreadLocal(为每个线程提供独立的变量副本)以及使用并发容器如ConcurrentHashMap等。 **三、JVM相关**...
- `newScheduledThreadPool`:创建定长线程池,支持定时和周期性任务。 - `newSingleThreadExecutor`:创建单线程线程池,确保任务按顺序执行。 3. **多线程取AaBbCc...**:这个问题可能考察线程同步和锁的使用,...
例如,数据同步、定时任务、分布式系统等,往往需要与不同的数据库进行交互。本文将深入探讨如何在Spring中配置和管理多个数据源。 首先,我们来看传统的单数据源配置。通常在Spring的`applicationContext.xml`中,...
22. **定时任务**:Java的ScheduledExecutorService或Quartz库可以实现定时任务。 23. **线程结束**:通常使用interrupt()方法或共享变量控制线程退出。 24. **Java锁机制**:包括synchronized、ReentrantLock、...
21. 定时器实现:定时任务可以通过java.util.Timer类或Spring Task来实现。 22. 线程退出方式:线程可以通过调用interrupt()方法、使用volatile的标志位或通过返回来退出。 23. Java锁类型:Java提供了多种锁机制...
- `handler`: 拒绝策略,当无法执行更多任务时使用。 - **底层实现**: - 通过`ExecutorService`接口和`ThreadPoolExecutor`实现类来创建和管理线程池。 #### 6. Synchronized与Lock - **Synchronized**: 内置锁...
51. **ThreadLocal的使用场景**:可以用来在多线程中存储每个线程自己的局部变量。 52. **synchronized底层实现原理**:当synchronized修饰方法时,通过monitorenter和monitorexit指令实现同步。当修饰代码块时,会...
│ 11-附录1.JS中局部变量和全局变量区别 │ d( L, Z2 p" ] ├─众筹项目-第05天《Atcrowdfunding》) A% ]3 K. N. T& e) [7 J │ ├─代码 │ ├─笔记 │ └─视频2 @8 e5 L% ~) b6 _) f. H: i │ 1-用户管理模块-...
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................