- 浏览: 62318 次
- 性别:
- 来自: 成都
文章分类
最新评论
//可以存取线程局部变量 //先看构造函数 public ThreadLocal() { } //设置值 public void set(T value) { Thread t = Thread.currentThread(); //这个Map以this为key ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } //继承了WeakReference说明这个key是自动回收的 static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal> { Object value; Entry(ThreadLocal k, Object v) { super(k); value = v; } } private void set(ThreadLocal key, Object value) { Entry[] tab = table; int len = tab.length; int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal k = e.get(); if (k == key) { e.value = value; return; } if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); } //获取保存的值 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); //有值则返回 if (e != null) return (T)e.value; } //返回初始化的值 return setInitialValue(); } //设置初始化的值 private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; } //覆盖这个方法获取初始值 protected T initialValue() { return null; } //删除值 public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); } /** 总结:ThreadLocal主要用于传递变量。如果要设置初始化的值可以直接覆盖initialValue()方法即可。 其原理是:将值存在一个ThreadLocalMap中。以自身为key,值为value。这个map继承了WeakReference。 说明其对于key是弱引用(相当于WeakHashMap)。 */
发表评论
-
读Exchanger源码
2017-10-10 11:38 327//用于线程间交换数据 public V exchang ... -
读Executors源码
2017-09-29 15:23 258//一个管理线程创建的类里面都是静态方法 //创建一 ... -
读ScheduledThreadPoolExecutor源码
2017-09-25 17:33 408//一个可以延迟执行的定时任务 //先看构造函数 构造函 ... -
读部分ThreadPoolExecutor源码
2017-09-25 15:27 303//线程池 //先看构造方法 public Threa ... -
读AbstractExecutorService
2017-09-23 16:34 320//他是ExecutorService的部分实现 pub ... -
读ExecutorCompletionService源码
2017-09-23 11:22 482//一个用来管理已完成任务的service,内部封装了一个 ... -
读FutureTask源码
2017-09-22 16:45 266//一个可以异步返回计算的结果 //它同时实现了Futu ... -
读ConcurrentSkipListMap源码
2017-09-21 15:11 287//数据结构是跳表 关于数据结构http://blog.c ... -
读Semaphore源码
2017-09-09 14:58 289//一个信号量,只有在池中还拥有许可时才允许线程继续执行。 ... -
读CyclicBarrier源码
2017-09-01 17:59 340//一个循环的屏障。所有的线程在屏障处等待其他线程执行完毕 ... -
读CountDownLatch源码
2017-09-01 14:01 319//在完成一组操作之前允许一个或多个线程等待内部用的AQS ... -
读ConcurrentLinkedQueue
2017-09-01 11:40 284//这是一个无阻塞的队列没有加任何锁全部利用CAS机制实现 ... -
读ConcurrentHashMap源码
2017-08-31 11:21 271//先看构造函数 public ConcurrentHa ... -
读CopyOnWriteArrayList源码
2017-08-22 12:59 404//在该集合上的写操作都是在原有的副本上进行的操作。这样可 ... -
读LinkedBlockingDeque源码
2017-08-21 14:26 553//这是一个支持双端操作的可阻塞队列 //先看构造函数 ... -
读SynchronousQueue源码
2017-08-10 10:51 371//先看构造方法 public SynchronousQ ... -
读PriorityBlocking源码
2017-08-09 13:47 352//一个基于而为堆的优先级队列,它是无界的。 //先看构 ... -
读DelayQueen源码
2017-08-07 15:16 271//一个基于二叉堆优先 ... -
LinkedblockingQueue源码解读
2017-08-04 13:03 345//LinkedBlockQueue //先看构造函数 ... -
ArrayBlockingQueue源码解读
2017-08-03 13:53 293//先看构造函数 //初始化一个给定容量的ArrayBl ...
相关推荐
通过自定义`CurrentDataSourceHolder`类或使用`ThreadLocal`来保存当前线程的数据源信息。在需要切换数据源的地方,更新这个信息,`AbstractRoutingDataSource`会自动识别并选择正确数据源。 6. **代码示例**: ...
- 在业务代码中,可以通过设置ThreadLocal变量来保存当前数据源的标识,然后在`AbstractRoutingDataSource`的实现中读取这个标识来决定使用哪个数据源。 - 另一种方式是在Service层或DAO层的接口上添加自定义注解...
- **数据源切换逻辑**:在业务逻辑中,可以通过设置ThreadLocal变量或者利用AOP(面向切面编程)来切换数据源。例如,读操作使用读库,写操作使用写库。 - **Mapper配置**:每个数据源的Mapper配置文件需要独立,...
6. **在代码中切换数据源**:在业务代码中,可以通过ThreadLocal或其他方式设置当前数据源的标识,使得在执行SQL操作时,Spring能够根据设定自动选择正确的数据源。 7. **读写分离**:多数据源的一个常见应用场景是...
- 在业务代码中,可以通过设置`DynamicDSHolder`中的数据源key来切换数据源。例如,在服务开始前,设置`DynamicDSHolder.setDsKey("primary")`,则后续的数据操作将使用`primaryDataSource`。 6. **AOP切面** - ...
5. **切换策略**:在实际项目中,数据源的切换策略可能会更复杂,例如通过AOP拦截器来判断请求类型(读/写)并设置当前数据源的key,或者使用ThreadLocal来存储数据源key等。 通过以上步骤,我们可以实现MyBatis的...
- 在`@Around`通知中,根据方法上的`@SwitchDataSource`注解的值,动态改变`ThreadLocal`中的数据源,使得后续的数据库操作使用指定的数据源。 3. **读写分离** - 读写分离的基本思想是:主库负责写操作,从库...
- `DynamicDataSourceRouter`:通常会有一个`Map`存储所有的数据源,并通过`ThreadLocal`或`RequestContextHolder`来保存当前选择的数据源。 - 在`@Service`或`@Repository`类中,使用`@Autowired`注入`DataSource...
创建一个自定义的`ThreadLocal`变量来保存当前线程所使用的数据源信息。 - 创建一个切面,拦截特定的注解,如`@DS`(代表Data Source),根据注解的值来切换数据源。 3. **MyBatisPlus的多数据源整合**: - ...
在Spring框架中,实现数据库的读写分离是提高系统性能的一种常见策略,它可以将读操作和写操作分散到不同的数据源上,减轻主数据库的压力。本文将详细介绍如何利用Spring配置动态数据源来实现这一功能。 首先,我们...
标题中的“Spring读写分离”指的是在基于Spring框架的应用中实现数据库的读写操作分离,以提高...对于标签中提到的“源码”,深入研究Spring和MyBatis的源代码可以帮助我们理解其内部工作原理,提升开发和调试能力。
2. **使用ThreadLocal确保线程安全**:由于数据源配置通常是单例模式,为保证线程安全,可以借助`ThreadLocal`类。 3. **实现AOP切面**:编写一个AOP切面,在业务方法调用前后分别设置和清除数据源标识。 #### 示例...
Java Annotation 是一种元数据,它允许我们在源代码中嵌入信息,这些信息可以被编译器或运行时环境用于处理代码。Annotation 不是代码本身,但可以影响代码的行为或提供编译时和运行时的元信息。它们在 Java 中的...
注解为元数据提供了一种机制,使得程序员可以在源代码中添加声明性信息,这些信息可以在编译时或运行时被处理。注解广泛应用于依赖注入、代码生成、验证等领域。 增强的for循环(也称为foreach循环)是JDK 5.0的另...
数据读写分离是数据库优化的重要策略,它将高并发的读操作和低频的写操作分配到不同的数据源上,以提高系统的性能和可用性。Spring和MyBatis框架结合,可以通过AOP(面向切面编程)和自定义插件来实现这一功能。 1....
5. **切换数据源**:在业务逻辑中,我们可以通过AOP或ThreadLocal等方式来实现数据源的动态切换。一种常见做法是创建一个事务管理器,根据事务的类型(如读/写)选择合适的数据源。 ```java @Configuration @...
- 在业务代码中,可以通过设置ThreadLocal变量或者利用AOP拦截器来实现数据源的切换。 6. **注意事项** - 为了避免数据源混乱,确保在使用不同数据源的Service或DAO层类前,正确地设置当前线程的数据源。 - 在多...
源代码阅读能力体现了开发者深入理解技术的能力。例如,阅读`HashMap`源码可以理解其内部实现,包括扩容策略、碰撞处理等。 以上是针对BAT面试中涉及的Java多线程、JVM、Java扩展、Spring、中间件、数据库和Redis等...
17. **源码阅读**:阅读和理解开源框架的源代码,如Spring、Hibernate等,有助于深入理解其工作原理。 18. **Redis**:内存数据存储系统,常用于缓存、消息队列等场景,掌握其数据类型、持久化策略、主从复制和...
创建一个ThreadLocal变量来保存当前线程所使用的数据源,然后在需要切换数据源的方法上添加自定义注解,AOP切面会在方法执行前后进行数据源的切换。 3. **事务管理** - 多数据源事务管理是较复杂的一部分。Spring...