当前位置: 首页 > news >正文

上海模板建站公司会员网站开发

上海模板建站公司,会员网站开发,wordpress 数据库类,网站备案为何要关站#x1f9d1; 博主简介#xff1a;CSDN博客专家#xff0c;历代文学网#xff08;PC端可以访问#xff1a;https://literature.sinhy.com/#/?__c1000#xff0c;移动端可微信小程序搜索“历代文学”#xff09;总架构师#xff0c;15年工作经验#xff0c;精通Java编… 博主简介CSDN博客专家历代文学网PC端可以访问https://literature.sinhy.com/#/?__c1000移动端可微信小程序搜索“历代文学”总架构师15年工作经验精通Java编程高并发设计Springboot和微服务熟悉LinuxESXI虚拟化以及云原生Docker和K8s热衷于探索科技的边界并将理论知识转化为实际应用。保持对新技术的好奇心乐于分享所学希望通过我的实践经历和见解启发他人的创新思维。在这里我希望能与志同道合的朋友交流探讨共同进步一起在技术的世界里不断学习成长。 技术合作请加本人wx注明来自csdnforeast_sea Java并发编程面试题ThreadLocal 1. ThreadLocal 是什么 ThreadLocal是 Java 中提供的一种用于实现线程局部变量的工具类。它允许每个线程都拥有自己的独立副本从而实现线程隔离用于解决多线程中共享对象的线程安全问题。 在 Web 应用中可以使用 ThreadLocal 存储用户会话信息这样每个线程在处理用户请求时都能方便地访问当前用户的会话信息。 在数据库操作中可以使用 ThreadLocal 存储数据库连接对象每个线程有自己独立的数据库连接从而避免了多线程竞争同一数据库连接的问题。 在格式化操作中例如日期格式化可以使用 ThreadLocal 存储 SimpleDateFormat 实例避免多线程共享同一实例导致的线程安全问题。 使用 ThreadLocal 通常分为四步 ①、创建 ThreadLocal //创建一个ThreadLocal变量 public static ThreadLocalString localVariable new ThreadLocal();②、设置 ThreadLocal 的值 //设置ThreadLocal变量的值 localVariable.set(沉默王二是沙雕);③、获取 ThreadLocal 的值 //获取ThreadLocal变量的值 String value localVariable.get();④、删除 ThreadLocal 的值 //删除ThreadLocal变量的值 localVariable.remove();ThreadLocal 有哪些优点 ①、线程隔离每个线程访问的变量副本都是独立的避免了共享变量引起的线程安全问题。由于 ThreadLocal 实现了变量的线程独占使得变量不需要同步处理因此能够避免资源竞争。 ②、数据传递方便ThreadLocal 常用于在跨方法、跨类时传递上下文数据如用户信息等而不需要在方法间传递参数。 除了 ThreadLocal还有什么解决线程安全问题的方法 ①、Java 中的 synchronized 关键字可以用于方法和代码块确保同一时间只有一个线程可以执行特定的代码段。 public synchronized void method() {// 线程安全的操作 }②、Java 并发包java.util.concurrent.locks中提供了 Lock 接口和一些实现类如 ReentrantLock。相比于 synchronizedReentrantLock 提供了公平锁和非公平锁。 ReentrantLock lock new ReentrantLock();public void method() {lock.lock();try {// 线程安全的操作} finally {lock.unlock();} }③、Java 并发包还提供了一组原子变量类如 AtomicIntegerAtomicLong 等它们利用 CAS比较并交换实现了无锁的原子操作适用于简单的计数器场景。 AtomicInteger atomicInteger new AtomicInteger(0);public void increment() {atomicInteger.incrementAndGet(); }④、Java 并发包提供了一些线程安全的集合类如 ConcurrentHashMapCopyOnWriteArrayList 等。这些集合类内部实现了必要的同步策略提供了更高效的并发访问。 ConcurrentHashMapString, String map new ConcurrentHashMap();⑤、volatile 变量保证了变量的可见性修改操作是立即同步到主存的读操作从主存中读取。 private volatile boolean flag false;2. 你在工作中用到过 ThreadLocal 吗 有用到过用来存储用户信息。 MVC 架构登录后的用户每次访问接口都会在请求头中携带一个 token在控制层可以根据这个 token解析出用户的基本信息。 假如在服务层和持久层也要用到用户信息就可以在控制层拦截请求把用户信息存入 ThreadLocal。 这样我们在任何一个地方都可以取出 ThreadLocal 中存的用户信息。 很多其它场景的 cookie、session 等等数据隔离都可以通过 ThreadLocal 去实现。 数据库连接池也可以用 ThreadLocal将数据库连接池的连接交给 ThreadLocal 进行管理能够保证当前线程的操作都是同一个 Connnection。 3. ThreadLocal 怎么实现的呢 ThreadLocal 本身并不存储任何值它只是作为一个映射来映射线程的局部变量。当一个线程调用 ThreadLocal 的 set 或 get 方法时实际上是访问线程自己的 ThreadLocal.ThreadLocalMap。 ThreadLocalMap 是 ThreadLocal 的静态内部类它内部维护了一个 Entry 数组key 是 ThreadLocal 对象value 是线程的局部变量本身。 早期的 ThreadLocal 不是这样的它的 ThreadLocalMap 中使用 Thread 作为 key这也是最简单的实现方式。 优化后的方案有两个好处一个是 Map 中存储的键值对变少了另一个是 ThreadLocalMap 的生命周期和线程一样长线程销毁的时候ThreadLocalMap 也会被销毁。 Entry 继承了 WeakReference它限定了 key 是一个弱引用弱引用的好处是当内存不足时JVM 会回收 ThreadLocal 对象并且将其对应的 Entry 的 value 设置为 null这样在很大程度上可以避免内存泄漏。 static class Entry extends WeakReferenceThreadLocal? {/** The value associated with this ThreadLocal. */Object value;//节点类Entry(ThreadLocal? k, Object v) {//key赋值super(k);//value赋值value v;} }ThreadLocal 的实现原理就是每个线程维护一个 Mapkey 为 ThreadLocal 对象value 为想要实现线程隔离的对象。 1、当需要存线程隔离的对象时通过 ThreadLocal 的 set 方法将对象存入 Map 中。 2、当需要取线程隔离的对象时通过 ThreadLocal 的 get 方法从 Map 中取出对象。 3、Map 的大小由 ThreadLocal 对象的多少决定。 什么是弱引用什么是强引用 强引用比如说 User user new User(沉默王二) 中user 就是一个强引用new User(沉默王二) 就是一个强引用对象。 当 user 被置为 null 时user nullnew User(沉默王二) 将会被垃圾回收如果 user 不被置为 null即便是内存空间不足JVM 也不会回收 new User(沉默王二) 这个强引用对象宁愿抛出 OutOfMemoryError。 弱引用比如说下面这段代码 ThreadLocalUser userThreadLocal new ThreadLocal(); userThreadLocal.set(new User(沉默王二));①、userThreadLocal 是一个强引用new ThreadLocal() 是一个强引用对象 ②、new User(沉默王二) 是一个强引用对象。 ③、在 ThreadLocalMap 中key new ThreadLocal() 是一个弱引用对象。当 JVM 进行垃圾回收时如果发现了弱引用对象就会将其回收。 其关系链就是 ThreadLocal 强引用 - ThreadLocal 对象。Thread 强引用 - ThreadLocalMap。ThreadLocalMap[i] 强引用了 - Entry。Entry.key 弱引用 - ThreadLocal 对象。Entry.value 强引用 - 线程的局部变量对象。 4. ThreadLocal 内存泄露是怎么回事 通常情况下随着线程 Thread 的结束其内部的 ThreadLocalMap 也会被回收从而避免了内存泄漏。 但如果一个线程一直在运行并且其 ThreadLocalMap 中的 Entry.value 一直指向某个强引用对象那么这个对象就不会被回收从而导致内存泄漏。当 Entry 非常多时可能就会引发更严重的内存溢出问题。 那怎么解决内存泄漏问题呢 很简单使用完 ThreadLocal 后及时调用 remove() 方法释放内存空间。 try {threadLocal.set(value);// 执行业务操作 } finally {threadLocal.remove(); // 确保能够执行清理 }remove() 方法会将当前线程的 ThreadLocalMap 中的所有 key 为 null 的 Entry 全部清除这样就能避免内存泄漏问题。 private void remove(ThreadLocal? key) {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)]) {if (e.get() key) {e.clear();expungeStaleEntry(i);return;}} }public void clear() {this.referent null; }那为什么 key 要设计成弱引用 弱引用的好处是当内存不足的时候JVM 会主动回收掉弱引用的对象。 比如说 WeakReference key new WeakReference(new ThreadLocal());key 是弱引用new WeakReference(new ThreadLocal()) 是弱引用对象当 JVM 进行垃圾回收时如果发现了弱引用对象就会将其回收。 一旦 key 被回收ThreadLocalMap 在进行 set、get 的时候就会对 key 为 null 的 Entry 进行清理。 总结一下在 ThreadLocal 被垃圾收集后下一次访问 ThreadLocalMap 时Java 会自动清理那些键为 null 的条目参照源码中的 replaceStaleEntry 方法这个过程会在执行 ThreadLocalMap 相关操作如 get(), set(), remove()时触发。 你了解哪些 ThreadLocal 的改进方案 在 JDK 20 Early-Access Build 28 版本中出现了 ThreadLocal 的改进方案即 ScopedValue。 还有 Netty 中的 FastThreadLocal它是 Netty 对 ThreadLocal 的优化它内部维护了一个索引常量 index每次创建 FastThreadLocal 中都会自动1用来取代 hash 冲突带来的损耗用空间换时间。 private final int index;public FastThreadLocal() {index InternalThreadLocalMap.nextVariableIndex(); } public static int nextVariableIndex() {int index nextIndex.getAndIncrement();if (index 0) {nextIndex.decrementAndGet();}return index; }5. ThreadLocalMap 的源码看过吗 ThreadLocalMap 虽然被叫做 Map其实它是没有实现 Map 接口的但是结构还是和 HashMap 比较类似的主要关注的是两个要素元素数组和散列方法。 元素数组 一个 table 数组存储 Entry 类型的元素Entry 是 ThreaLocal 弱引用作为 keyObject 作为 value 的结构。 private Entry[] table;散列方法 散列方法就是怎么把对应的 key 映射到 table 数组的相应下标ThreadLocalMap 用的是哈希取余法取出 key 的 threadLocalHashCode然后和 table 数组长度减一运算相当于取余。 int i key.threadLocalHashCode (table.length - 1);这里的 threadLocalHashCode 计算有点东西每创建一个 ThreadLocal 对象它就会新增0x61c88647这个值很特殊它是斐波那契数 也叫 黄金分割数。hash增量为 这个数字带来的好处就是 hash 分布非常均匀。 private static final int HASH_INCREMENT 0x61c88647;private static int nextHashCode() {return nextHashCode.getAndAdd(HASH_INCREMENT);}6. ThreadLocalMap 怎么解决 Hash 冲突的 我们可能都知道 HashMap 使用了链表来解决冲突也就是所谓的链地址法。 ThreadLocalMap 没有使用链表自然也不是用链地址法来解决冲突了它用的是另外一种方式——开放定址法。开放定址法是什么意思呢简单来说就是这个坑被人占了那就接着去找空着的坑。 如上图所示如果我们插入一个 value27 的数据通过 hash 计算后应该落入第 4 个槽位中而槽位 4 已经有了 Entry 数据而且 Entry 数据的 key 和当前不相等。此时就会线性向后查找一直找到 Entry 为 null 的槽位才会停止查找把元素放到空的槽中。 在 get 的时候也会根据 ThreadLocal 对象的 hash 值定位到 table 中的位置然后判断该槽位 Entry 对象中的 key 是否和 get 的 key 一致如果不一致就判断下一个位置。 7. ThreadLocalMap 扩容机制了解吗 在 ThreadLocalMap.set()方法的最后如果执行完启发式清理工作后未清理到任何数据且当前散列数组中Entry的数量已经达到了列表的扩容阈值(len*2/3)就开始执行rehash()逻辑 if (!cleanSomeSlots(i, sz) sz threshold)rehash();再着看 rehash()具体实现这里会先去清理过期的 Entry然后还要根据条件判断size threshold - threshold / 4 也就是size threshold* 3/4来决定是否需要扩容。 private void rehash() {//清理过期EntryexpungeStaleEntries();//扩容if (size threshold - threshold / 4)resize(); }//清理过期Entry private void expungeStaleEntries() {Entry[] tab table;int len tab.length;for (int j 0; j len; j) {Entry e tab[j];if (e ! null e.get() null)expungeStaleEntry(j);} } 接着看看具体的resize()方法扩容后的newTab的大小为老数组的两倍然后遍历老的 table 数组散列方法重新计算位置开放地址解决冲突然后放到新的newTab遍历完成之后oldTab中所有的entry数据都已经放入到newTab中了然后 table 引用指向newTab 具体代码 8. 父子线程怎么共享数据 父线程能用 ThreadLocal 来给子线程传值吗毫无疑问不能。那该怎么办 这时候可以用到另外一个类——InheritableThreadLocal 。 使用起来很简单在主线程的 InheritableThreadLocal 实例设置值在子线程中就可以拿到了。 public class InheritableThreadLocalTest {public static void main(String[] args) {final ThreadLocal threadLocal new InheritableThreadLocal();// 主线程threadLocal.set(不擅技术);//子线程Thread t new Thread() {Overridepublic void run() {super.run();System.out.println(鄙人三某 threadLocal.get());}};t.start();} }那原理是什么呢 原理很简单在 Thread 类里还有另外一个变量 ThreadLocal.ThreadLocalMap inheritableThreadLocals null;在 Thread.init 的时候如果父线程的inheritableThreadLocals不为空就把它赋给当前线程子线程的inheritableThreadLocals 。 if (inheritThreadLocals parent.inheritableThreadLocals ! null)this.inheritableThreadLocals ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
http://www.w-s-a.com/news/642599/

相关文章:

  • 做外贸是不是必须有网站wordpress网络图片
  • 赣县企业网站建设用dw做网站的基本步骤
  • 辽源网站建设微信小程序公众平台
  • 多媒体网站设计开发是指什么常宁网站建设
  • 淄博网站推广优化17岁在线观看免费高清完整版
  • 企业形象网站开发业务范畴wordpress最好最全的教程
  • 企业网站的建立意义网站首页制作网站
  • 网站制作过程内容深圳最好的活动策划公司
  • 深圳网站关键词排名查询公司网站怎么做啊
  • 微网站 制作平台广州电商聚集地
  • 建设外国商城网站网站服务器 虚拟主机
  • 天河网站建设开发电子商务公司名字大全
  • 站长推荐为何用wdcp建立网站连不上ftp
  • 云南旅行社网站开发学编程多久可以写游戏辅助
  • 推广网站的步骤网站备案号中信息有变
  • 优秀企业建站织梦能不能做门户网站
  • 广东省建设局官方网站wordpress 自动安装 插件怎么用
  • 哪类小网站容易做h5页面制作代码
  • 北京网站建设公司华网百度热搜seo
  • 小清新博客网站中山做网站公司
  • 美团做团购网站如何新建自己的网站
  • 安卓软件制作网站电子商务网站建设实训总结报告
  • 肃宁网站制作价格外国设计师素材网站
  • 自已建网站用jsp做的可运行的网站
  • 外贸建站代理网站建设设计公司哪家好
  • 普升高端品牌网站建设台州中兴建设咨询有限公司网站
  • 模板演示网站移动网站开发公司
  • 网站管理办法制度公司招聘信息
  • 宜昌市建设监理协会网站免备案免费域名
  • 河北省建设银行网站首页备案号怎么放到网站