ThreadLocal
ThreadLocal是什么?
ThreadLocal是Java中的一个类,它可以让你独立的创建一个线程本地变量。这个变量对于每个线程来说都是独立的,也就是说,每个线程都有自己的变量副本。这个类通常用于多线程编程中,因为它阻隔了你在多个线程之间共享同一个数据,因而不需要担心线程安全问题。
ThreadLocal简介
ThreadLocal叫做线程变量,意思是在ThreadLocal中填充的变量是属于当前线程的,该变量对于其他线程而言是隔离的,也就是说该变量是当前线程独有的变量
同一个ThreadLocal所包含的对象,在不同的Thread中有不同的副本:
1、对某个Thread来说,其内部的副本只能当前thread使用
2、其他的thread不能访问该thread副本,因而就不存在线程间的共享问题
ThreadLocal和Synchronized的区别?
ThreadLocal就是与线程绑定的一个变量,至于ThreadLocal和Synchronized则是有着本质上的区别
1、Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离
2、Synchronized利用的是锁的机制,使得变量或者代码块在同一时间只能被一个线程访问,而ThreadLocal则为每一个线程都提供了变量的副本,使得线程在同一时间访问到的并不是同一个对象,这样就阻隔了的多线程间的数据共享
set与get的使用
ThreadLocalMap 是 Java 中 ThreadLocal 的内部数据结构,用于存储线程本地变量的值。它是 ThreadLocal 类的内部私有类,并在 ThreadLocal 实例中管理线程本地变量的数据。其中,参数 K 代表 ThreadLocal 对象自身。
在 ThreadLocal 中,每个线程都有一个对应的 ThreadLocalMap 实例,用于存储线程本地变量的值。ThreadLocalMap 中的键(K)是具体的 ThreadLocal 实例,而值则是线程本地变量的值。
当在某个线程中调用 ThreadLocal 的 set 方法时,实际上是在该线程的 ThreadLocalMap 中以 ThreadLocal 实例作为键,将相应的值存储在 ThreadLocalMap 中。同样,当你在线程中调用 ThreadLocal 的 get 方法时,它会从当前线程的 ThreadLocalMap 中查找与 ThreadLocal 对象关联的值。
ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> null);
// 在线程1中设置值
Thread thread1 = new Thread(() -> {
threadLocal.set("Value for Thread 1");
String value = threadLocal.get();
System.out.println("Thread 1 - ThreadLocal value: " + value);
});
thread1.start();
// 在线程2中设置值
Thread thread2 = new Thread(() -> {
threadLocal.set("Value for Thread 2");
String value = threadLocal.get();
System.out.println("Thread 2 - ThreadLocal value: " + value);
});
thread2.start();
// 获取当前线程的值
String currentValue = threadLocal.get();
System.out.println("Main Thread - ThreadLocal value: " + currentValue);
// 等待两个线程执行完毕
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
可以看到线程1和2set了所以能get到
remove
ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> "Initial Value");
// 获取当前线程的线程本地变量的值
String value = threadLocal.get();
System.out.println("Initial Value: " + value);
// 移除当前线程的线程本地变量的值
threadLocal.remove();
// 再次获取当前线程的线程本地变量的值
String removedValue = threadLocal.get();
System.out.println("Value after remove: " + removedValue);
在这个示例中,我们首先获取了线程本地变量的值,然后使用remove()方法将其移除。再次获取值时,将返回线程本地变量的初始值(如果通过withInitial方法指定了初始值)或者null(如果未指定初始值)
public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier)
ThreadLocal<String> threadLocal = ThreadLocal.withInitial(() -> "Initial Value");
// 如果线程没有设置值,则获取初始值
String value = threadLocal.get();
System.out.println("Initial Value: " + value);
(偏个题)redis中常用的淘汰策略
Redis 中常见的淘汰策略:
NoEviction(不淘汰):当内存不足以容纳新写入数据时,新写入操作会报错。这个策略适用于需要保证数据完整性的场景。
AllKeysLRU(最近最少使用):从所有的键中选择最近最少使用的键进行淘汰。这是 Redis 默认的淘汰策略。
VolatileLRU(最近最少使用,仅限于过期键):从设置了过期时间的键中选择最近最少使用的键进行淘汰。
AllKeysRandom(随机淘汰):随机选择一个键进行淘汰。
VolatileRandom(随机淘汰,仅限于过期键):从设置了过期时间的键中随机选择一个键进行淘汰。
VolatileTTL(根据键的剩余生存时间进行淘汰):根据键的剩余生存时间进行淘汰,优先淘汰剩余生存时间较短的键。
VolatileLFU(最不经常使用,仅限于过期键):从设置了过期时间的键中选择最不经常使用的键进行淘汰。
AllKeysLFU(最不经常使用):从所有的键中选择最不经常使用的键进行淘汰。
需要注意的是,以上策略中带有 “Volatile” 的表示仅适用于设置了过期时间的键,而不带 “Volatile”
的适用于所有键。可以通过配置 Redis 的 maxmemory-policy 参数来选择合适的淘汰策略。
其中noeviction是默认策略。如果需要启用其他策略,可以通过修改Redis配置文件来实现