当前位置: 首页 > news >正文 p2p网站建设方案优化百度seo技术搜索引擎 news 2025/11/3 15:59:58 p2p网站建设方案,优化百度seo技术搜索引擎,成都小程序开发方案,网络营销文章目录#xff1a; 1.什么是ThreadLocal#xff1f; 1.1 api介绍 1.2 最简单的案例认识ThreadLocal 1.3 线程池结合ThreadLocal案例 2.Thread ThreadLocal ThreadLocalMap 3.ThreadLocal内存泄漏问题 3.1 四大引用之强引用 3.2 四大引用之软引用 3.3 四…文章目录 1.什么是ThreadLocal 1.1 api介绍 1.2 最简单的案例认识ThreadLocal 1.3 线程池结合ThreadLocal案例 2.Thread ThreadLocal ThreadLocalMap 3.ThreadLocal内存泄漏问题 3.1 四大引用之强引用 3.2 四大引用之软引用 3.3 四大引用之弱引用 3.4 四大引用之虚引用 3.5 ThreadLocal为什么是弱引用 4.小总结 1.什么是ThreadLocal ThreadLocal提供线程局部变量这些变量与正常的变量不同因为每一个线程在访问ThreadLocal实例的时候通过其get或set方法都有自己的、独立初始化的变量副本。 ThreadLocal实例通常是类中的私有静态字段使用它的目的是希望将状态例如用户ID或事务ID与线程关联起来。 实现每一个线程都有自己专属的本地变量副本(自己用自己的变量不麻烦别人不和其他人共享人人有份人各一份)主要解决了让每个线程绑定自己的值通过使用get()和set()方法获取默认值或将其值更改为当前线程所存的副本的值从而避免了线程安全问题。 1.1 api介绍 ThreadLocal是位于 java.lang 包下的从jdk官方文档中可以看到它所有的api。而它的构造方法其实就是 withInitial(Supplier)。 1.2 最简单的案例认识ThreadLocal 希望各自分灶吃饭各凭销售本事提成按照出单数各自统计。比如某房产中介销售都有自己的销售额指标自己专属于自己的不和别人掺和。 使用ThreadLocal 先初始化给个0值 利用set get方法 ------注意也要调用remove( 接口不然容易导致内存泄漏。在阿里巴巴Java开发手册中也有说明 package com.juc.threadlocal;import java.util.Random; import java.util.concurrent.TimeUnit;/*** author: SongZiHao* date: 2023/2/13*/ class House {public int saleCount 0;public synchronized void saleHouse() {saleCount;}// ThreadLocalInteger saleVolume new ThreadLocalInteger() { // Override // protected Integer initialValue() { // return 0; // } // };ThreadLocalInteger saleVolume ThreadLocal.withInitial(() - 0);public void saleVolumeByThreadLocal() {saleVolume.set(saleVolume.get() 1);} }public class ThreadLocalDemo1 {public static void main(String[] args) {House house new House();for (int i 0; i 5; i) {new Thread(() - {int size new Random().nextInt(5) 1;try {for (int j 0; j size; j) {house.saleHouse();house.saleVolumeByThreadLocal();}System.out.println(Thread.currentThread().getName() 号销售卖出多少套 house.saleVolume.get());} finally {house.saleVolume.remove();}}, String.valueOf(i)).start();}try {TimeUnit.MILLISECONDS.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() 共计卖出多少套 house.saleCount);} }1.3 线程池结合ThreadLocal案例 根据阿里规范需要对自定义的ThreadLocal进行回收否则容易造成内存泄漏和业务逻辑问题(因为线程池中的线程会复用)。 package com.juc.threadlocal;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** author: SongZiHao* date: 2023/2/13*/ class MyData {ThreadLocalInteger threadLocal ThreadLocal.withInitial(() - 0);public void add() {threadLocal.set(threadLocal.get() 1);} }public class ThreadLocalDemo2 {public static void main(String[] args) {MyData data new MyData();ExecutorService threadPool Executors.newFixedThreadPool(3);try {for (int i 0; i 10; i) {threadPool.submit(() - {try {Integer beforeValue data.threadLocal.get();data.add();Integer afterValue data.threadLocal.get();System.out.println(Thread.currentThread().getName() before: beforeValue , after: afterValue);} finally {data.threadLocal.remove();}});}} catch (Exception ex) {ex.printStackTrace();} finally {threadPool.shutdown();}} }如果上面的代码没有 finally remove 了话那么每个线程的value值就会累积变成2、3、4等等这是因为这些线程会被复用。 2.Thread ThreadLocal ThreadLocalMap 我们如果随便翻翻源码了话可能会经常看到三个类ThreadThreadLocalThreadLocalMap。 根据官方APIThread是程序中执行的线程ThreadLocal类提供线程局部变量。 先打开Thread.java类发现每个Thread类里面有一个ThreadLocal类而ThreadLocalMap是ThreadLocal的一个静态内部类。 下面是ThreadLocalMap这个静态内部类熟悉HashMap的同学看到这里肯定不陌生还是熟悉的配方、还是熟悉的味道设置k-v键值对初始化容量16。 threadLocalMap实际上就是一个以threadLocal实例为key任意对象为value的Entry对象。 当我们为threadLocal变量赋值实际上就是以当前threadLocal实例为key值为value的Entry往这个threadLocalMap中存放。 JVM内部维护了一个线程版的MapThread, T(通过ThreadLocal对象的set方法结果把ThreadLocal对象自己当做key放进了ThreadLoalMap中每个线程要用到这个T的时候用当前的线程去Map里面获取通过这样让每个线程都拥有了自己独立的变量人手一份竞争条件被彻底消除在并发模式下是绝对安全的变量。 每个Thread对象维护着一个ThreadLocalMap的引用。ThreadLocalMap是ThreadLocal的内部类用Entry来进行存储。 调用ThreadLocal的set()方法时实际上就是往ThreadLocalMap设置值key是ThreadLocal对象值Value是传递进来的对象。调用ThreadLocal的get()方法时实际上就是往ThreadLocalMap获取值key是ThreadLocal对象。ThreadLocal本身并不存储值它只是自己作为一个key来让线程从ThreadLocalMap获取value正因为这个原理所以ThreadLocal能够实现“数据隔离”获取当前线程的局部变量值不受其他线程影响。 Thread就是一个大活人ThreadLocal就是身份证原件ThreadLocalMap就是身份证上的信息姓名张三出生年月xxxx年y月z日这不就是个k-v的Map吗 那么ThreadThreadLocalThreadLocalMap三者可以用下面这张图概括。 3.ThreadLocal内存泄漏问题 3.1 四大引用之强引用 Java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。 官方API: finalize()的通常目的是在对象被不可撤销地丢弃之前执行清理操作。(我自己理解某个对象被干掉前还会调用finalize()清理一下 Reference是强引用SoftReference是软引用WeakReference是弱引用PhantomReference是虚引用强引用 当内存不足JVM开始垃圾回收对于强引用的对象就算是出现了OOM也不会对该对象进行回收死都不收。强引用是我们最常见的普通对象引用只要还有强引用指向一个对象就能表明对象还“活着”垃圾收集器不会碰这种对象。在 Java 中最常见的就是强引用把一个对象赋给一个引用变量这个引用变量就是一个强引用。当一个对象被强引用变量引用时它处于可达状态它是不可能被垃圾回收机制回收的即使该对象以后永远都不会被用到JVM也不会回收。因此强引用是造成Java内存泄漏的主要原因之一。对于一个普通的对象如果没有其他的引用关系只要超过了引用的作用域或者显式地将相应强引用赋值为 null一般认为就是可以被垃圾收集的了(当然具体回收时机还是要看垃圾收集策略)。package com.juc.threadlocal;import java.lang.ref.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;/*** author: SongZiHao* date: 2023/2/13*/ class MyObject {//finalize方法一般不会重写也不需要我们手动调用这里为了演示案例才这样写Overrideprotected void finalize() throws Throwable {//在对象被不可撤销的丢弃之前执行清理操作System.out.println(---- invoke finalize method ----);} }public class ReferenceDemo {public static void main(String[] args) {strongReference();}/*** 默认模式强引用*/private static void strongReference() {MyObject obj new MyObject();System.out.println(gc before: obj);obj null;System.gc(); //演示案例这里手动gc一般不会这样做System.out.println(gc after: obj);} } 3.2 四大引用之软引用 软引用是一种相对强引用弱化了一些的引用需要用java.lang.ref.SoftReference类来实现可以让对象豁免一些垃圾收集。 对于只有软引用的对象来说当系统内存充足时它 不会 被回收当系统内存不足时它 会 被回收。 软引用通常用在对内存敏感的程序中比如高速缓存就有用到软引用内存够用的时候就保留不够用就回收 演示案例先调整一下JVM的参数如下 package com.juc.threadlocal;import java.lang.ref.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;/*** author: SongZiHao* date: 2023/2/13*/ class MyObject {//finalize方法一般不会重写也不需要我们手动调用这里为了演示案例才这样写Overrideprotected void finalize() throws Throwable {//在对象被不可撤销的丢弃之前执行清理操作System.out.println(---- invoke finalize method ----);} }public class ReferenceDemo {public static void main(String[] args) {softReference();}/*** 软引用*/private static void softReference() {SoftReferenceMyObject softReference new SoftReference(new MyObject());System.out.println(gc before 内存够用: softReference.get());System.gc(); //演示案例这里手动gc一般不会这样做try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(gc after 内存仍够用: softReference.get()); //软引用gc之后内存够用就不会回收对象try {byte[] bytes new byte[20 * 1024 * 1024]; //20MB对象内存肯定不够用了} catch (Exception ex) {ex.printStackTrace();} finally {System.out.println(gc after 内存不够用: softReference.get()); //gc之后内存不够用就会回收对象}} }3.3 四大引用之弱引用 弱引用需要用java.lang.ref.WeakReference类来实现它比软引用的生存期更短 对于只有弱引用的对象来说只要垃圾回收机制一运行不管JVM的内存空间是否足够都会回收该对象占用的内存。 package com.juc.threadlocal;import java.lang.ref.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;/*** author: SongZiHao* date: 2023/2/13*/ class MyObject {//finalize方法一般不会重写也不需要我们手动调用这里为了演示案例才这样写Overrideprotected void finalize() throws Throwable {//在对象被不可撤销的丢弃之前执行清理操作System.out.println(---- invoke finalize method ----);} }public class ReferenceDemo {public static void main(String[] args) {weakReference();}/*** 弱引用*/private static void weakReference() {WeakReferenceMyObject weakReference new WeakReference(new MyObject());System.out.println(gc before 内存够用: weakReference.get());System.gc();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(gc after 内存够用: weakReference.get());} }3.4 四大引用之虚引用 虚引用必须和引用队列 (ReferenceQueue)联合使用。虚引用需要java.lang.ret.PhantomReterence类来实现顾名思义就是形同虚设与其他几种引用都不同虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用那么它就和没有任何引用一样在任何时候都可能被垃圾回收器回收它不能单独使用也不能通过它访问对象虚引用必须和引用队列(ReferenceQueue)联合使用。PhantomReference的get方法总是返回null因此无法访问对应的引用对象。虚引用的主要作用是跟踪对象被垃圾回收的状态。仅仅是提供了一种确保对象被 finalize以后做某些事情的通知机制。处理监控通知使用换句话说设置虚引用关联对象的唯一目的就是在这个对象被收集器回收的时候收到一个系统通知或者后续添加进一步的处理用来实现比finalize机制更灵活的回收操作。案例如下记得先给JVM参数设置成-Xms10m -Xmx10m 。 package com.juc.threadlocal;import java.lang.ref.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit;/*** author: SongZiHao* date: 2023/2/13*/ class MyObject {//finalize方法一般不会重写也不需要我们手动调用这里为了演示案例才这样写Overrideprotected void finalize() throws Throwable {//在对象被不可撤销的丢弃之前执行清理操作System.out.println(---- invoke finalize method ----);} }public class ReferenceDemo {public static void main(String[] args) {phantomReference();}/*** 虚引用*/private static void phantomReference() {MyObject obj new MyObject();ReferenceQueueMyObject referenceQueue new ReferenceQueue();PhantomReferenceMyObject phantomReference new PhantomReference(obj, referenceQueue);System.out.println(phantomReference.get()); //虚引用get方法总是返回nullListbyte[] list new ArrayList();new Thread(() - {while (true) {//一共10M内存死循环每次向list中存1MB数据list.add(new byte[1 * 1024 * 1024]);try {TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(phantomReference.get() list add ok....);}}, t1).start();new Thread(() - {while (true) {Reference? extends MyObject reference referenceQueue.poll();if (reference ! null) {System.out.println(有虚对象被回收加入了队列....);break;}}}, t2).start();} }由于这里的代码执行结果不一定会成功打印有虚对象被回收加入了队列这句话所以我直接把周阳老师的图抓了过来。 3.5 ThreadLocal为什么是弱引用 当function01方法执行完毕后栈帧销毁强引用 tl 也就没有了。但此时线程的ThreadLocalMap里某个entry的key引用还指向这个对象。 若这个key引用是强引用就会导致key指向的ThreadLocal对象及v指向的对象不能被gc回收造成内存泄漏若这个key引用是弱引用就大概率会减少内存泄漏的问题。使用弱引用就可以使ThreadLocal对象在方法执行完毕后顺利被回收且Entry的key引用指向为null。 ThreadLocalMap使用ThreadLocal的弱引用作为key如果一个ThreadLocal没有外部强引用引用他那么系统gc的时候这个ThreadLocal势必会被回收这样一来ThreadLocalMap中就会出现key为null的Entry就没有办法访问这些key为null的Entry的value如果当前线程再迟迟不结束的话(比如正好用在线程池)这些key为null的Entry的value就会一直存在一条强引用链。 虽然弱引用保证了key指向的ThreadLocal对象能被及时回收但是v指向的value对象是需要ThreadLocalMap调用get、set时发现key为null时才会去回收整个entry、value因此弱引用不能100%保证内存不泄露。我们要在不使用某个ThreadLocal对象后手动调用方法来删除它尤其是在线程池中不仅仅是内存泄露的问题因为线程池中的线程是重复使用的意味着这个线程的ThreadLocalMap对象也是重复使用的如果我们不手动调用remove方法那么后面的线程就有可能获取到上个线程遗留下来的value值造成bug。 结论在不使用某个ThreadLocal对象后手动调用remove方法来删除它尤其是防止线程池下的复用从前面的setgetremove方法的源码中可以看出在threadLocal的生命周期里针对threadLocal存在的内存泄漏的问题都会通过expungeStaleEntry、cleanSomeSlots、replaceStaleEntry 这三个方法清理掉key为null的脏entry。4.小总结 使用ThreadLocal一定要进行初始化避免空指针问题。 ThreadLocal.withInitial(() - 0) 建议把ThreadLocal修饰为static。 用完记得手动remove。 文章转载自: http://www.morning.qpljg.cn.gov.cn.qpljg.cn http://www.morning.beijingzy.com.cn.gov.cn.beijingzy.com.cn http://www.morning.pndw.cn.gov.cn.pndw.cn http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn http://www.morning.bzwxr.cn.gov.cn.bzwxr.cn http://www.morning.phgz.cn.gov.cn.phgz.cn http://www.morning.splcc.cn.gov.cn.splcc.cn http://www.morning.xnlj.cn.gov.cn.xnlj.cn http://www.morning.pdkht.cn.gov.cn.pdkht.cn http://www.morning.llyjx.cn.gov.cn.llyjx.cn http://www.morning.khzml.cn.gov.cn.khzml.cn http://www.morning.bwjws.cn.gov.cn.bwjws.cn http://www.morning.gbfzy.cn.gov.cn.gbfzy.cn http://www.morning.ynlpy.cn.gov.cn.ynlpy.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.npcxk.cn.gov.cn.npcxk.cn http://www.morning.fwqgy.cn.gov.cn.fwqgy.cn http://www.morning.nlzpj.cn.gov.cn.nlzpj.cn http://www.morning.zycll.cn.gov.cn.zycll.cn http://www.morning.fbmjl.cn.gov.cn.fbmjl.cn http://www.morning.pjtw.cn.gov.cn.pjtw.cn http://www.morning.lnmby.cn.gov.cn.lnmby.cn http://www.morning.zfkxj.cn.gov.cn.zfkxj.cn http://www.morning.jnhhc.cn.gov.cn.jnhhc.cn http://www.morning.bsrp.cn.gov.cn.bsrp.cn http://www.morning.qnhpq.cn.gov.cn.qnhpq.cn http://www.morning.hyxwh.cn.gov.cn.hyxwh.cn http://www.morning.tzzfy.cn.gov.cn.tzzfy.cn http://www.morning.srbbh.cn.gov.cn.srbbh.cn http://www.morning.rfpb.cn.gov.cn.rfpb.cn http://www.morning.njntp.cn.gov.cn.njntp.cn http://www.morning.nwfxp.cn.gov.cn.nwfxp.cn http://www.morning.kllzy.com.gov.cn.kllzy.com http://www.morning.rpsjh.cn.gov.cn.rpsjh.cn http://www.morning.duqianw.com.gov.cn.duqianw.com http://www.morning.dydqh.cn.gov.cn.dydqh.cn http://www.morning.kwrzg.cn.gov.cn.kwrzg.cn http://www.morning.zhmgcreativeeducation.cn.gov.cn.zhmgcreativeeducation.cn http://www.morning.rkkh.cn.gov.cn.rkkh.cn http://www.morning.xkzr.cn.gov.cn.xkzr.cn http://www.morning.sftrt.cn.gov.cn.sftrt.cn http://www.morning.qgjxt.cn.gov.cn.qgjxt.cn http://www.morning.nkrmh.cn.gov.cn.nkrmh.cn http://www.morning.nqxdg.cn.gov.cn.nqxdg.cn http://www.morning.yznsx.cn.gov.cn.yznsx.cn http://www.morning.fynkt.cn.gov.cn.fynkt.cn http://www.morning.btnmj.cn.gov.cn.btnmj.cn http://www.morning.nxtgb.cn.gov.cn.nxtgb.cn http://www.morning.nqlnd.cn.gov.cn.nqlnd.cn http://www.morning.clhyj.cn.gov.cn.clhyj.cn http://www.morning.bpmfn.cn.gov.cn.bpmfn.cn http://www.morning.dmzqd.cn.gov.cn.dmzqd.cn http://www.morning.prsxj.cn.gov.cn.prsxj.cn http://www.morning.ckntb.cn.gov.cn.ckntb.cn http://www.morning.jgcrr.cn.gov.cn.jgcrr.cn http://www.morning.kcrw.cn.gov.cn.kcrw.cn http://www.morning.ghlyy.cn.gov.cn.ghlyy.cn http://www.morning.frxsl.cn.gov.cn.frxsl.cn http://www.morning.rtjhw.cn.gov.cn.rtjhw.cn http://www.morning.tqfnf.cn.gov.cn.tqfnf.cn http://www.morning.smtrp.cn.gov.cn.smtrp.cn http://www.morning.gwwtm.cn.gov.cn.gwwtm.cn http://www.morning.dxqfh.cn.gov.cn.dxqfh.cn http://www.morning.yqmmh.cn.gov.cn.yqmmh.cn http://www.morning.dgng.cn.gov.cn.dgng.cn http://www.morning.mbaiwan.com.gov.cn.mbaiwan.com http://www.morning.xjkfb.cn.gov.cn.xjkfb.cn http://www.morning.yjdql.cn.gov.cn.yjdql.cn http://www.morning.yhrfg.cn.gov.cn.yhrfg.cn http://www.morning.lgwjh.cn.gov.cn.lgwjh.cn http://www.morning.deanzhu.com.gov.cn.deanzhu.com http://www.morning.rflcy.cn.gov.cn.rflcy.cn http://www.morning.mpgfk.cn.gov.cn.mpgfk.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.nrpp.cn.gov.cn.nrpp.cn http://www.morning.grbgn.cn.gov.cn.grbgn.cn http://www.morning.zrfwz.cn.gov.cn.zrfwz.cn http://www.morning.wpmqq.cn.gov.cn.wpmqq.cn http://www.morning.rzcbk.cn.gov.cn.rzcbk.cn http://www.morning.ssglh.cn.gov.cn.ssglh.cn 查看全文 http://www.tj-hxxt.cn/news/274133.html 相关文章: 一元购网站怎么做my23777免费域名查询 分类目录企业网站seo优化怎么做 做网站推广的 什么是开户在线看视频网站怎么做的 企业内训课程seo 网站标题长度 婚庆 网站模板北京做视觉网站 上海青浦网站建设百度搜索引擎优化的推广计划 男女做污的事情网站视频南谯区住房和城乡建设局网站 汕尾住房和城乡建设局网站wordpress服务器 工具用具使用费是指企业施工生产郑州seo排名优化 php旅游类网站开发如何给自己的店做小程序 福建网站建设费用同ip网站做301 四川省住房城乡建设厅网站首页h5就是手机端网页吗 石家庄网站建设培训同ip多域名做同行业网站 如何建立优秀企业网站wordpress文章显示软件下载 佳匠网站建设广州网站建设公司哪个好 陈村网站建设学校门户网站作用 软件下载网站地址专做阀门网站 做网站有维护费是什么费用信用中国门户网站建设方案 学网站开发看什么书百度2020新版下载 网站域名过期怎么办手机网站建设商场 哪家公司建设网站好企业网站建设哪家效果好 h5商城网站建站一个公司的网站怎么做的 建设网站一般多钱安康做网站的公司电话 网站设计制作用软件建设网站的风险6 禁止指定ip访问网站网站案例演示 计算机网站建设员wordpress isadmin 南通网站建设总结网络规划设计师书籍 网页怎么写太原seo代理计费 网站建设预算表制作wordpress简体中文版下载 淘宝做短视频网站好湖南省建设局网站