IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JAVA多线程-ThreadLocal线程局部变量和强软弱虚四种引用 -> 正文阅读

[Java知识库]JAVA多线程-ThreadLocal线程局部变量和强软弱虚四种引用

ThreadLocal线程局部变量

ThreadLocal是使用空间换时间,synchronized是使用时间换空间,比如在hibernate中session就存在与ThreadLocal中,避免synchronized的使用。

import java.util.concurrent.TimeUnit;
public class ThreadLocal2 {
	//volatile static Person p = new Person();
	static ThreadLocal<Person> tl = new ThreadLocal<>();
	
	public static void main(String[] args) {
				
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(tl.get());
		}).start();
		
		new Thread(()->{
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			tl.set(new Person());
		}).start();
	}
	
	static class Person {
		String name = "zhangsan";
	}
}
//1秒后  设置值 2秒后访问不了  因为ThreadLocal是线程独有的

先获取到当前的线程Thread,根据当前线程获取ThreadLocalMap返回,然后再Map中set
在这里插入图片描述
根据当前线程获取ThreadLocalMap返回
在这里插入图片描述
获取当前线程的threadLocals
在这里插入图片描述

强引用

重写finalize,当垃圾回收会调用打印输出"finalize"

public class M {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize");
    }
}

当指向为null的时候会被回收


import java.io.IOException;

public class T01_NormalReference {
    public static void main(String[] args) throws IOException {
        M m = new M();
        m = null;
        System.gc(); //DisableExplicitGC

        System.in.read();
    }
}
//有引用指向不会垃圾回收  M m = new M(); m 强引用

软引用

对象被软引用指向 系统内存不够用了才会回收
存够用即使GC也不会回收软引用 内存不够清理软引用

/**
 * 软引用
 * 软引用是用来描述一些还有用但并非必须的对象。
 * 对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围进行第二次回收。
 * 如果这次回收还没有足够的内存,才会抛出内存溢出异常。
 * -Xmx20M
 */
import java.lang.ref.SoftReference;

public class T02_SoftReference {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024*1024*10]);//栈内存m指向堆软引用对象  软引用对象里面有个引用指向了一个字节数组
        //m = null;
        System.out.println(m.get());//拿到字节数组 输出hashcode
        System.gc();//运行垃圾回收 FullGc
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());//如果被回收会输出null

        //再分配一个数组,heap将装不下,这时候系统会垃圾回收,先回收一次,如果不够,会把软引用干掉
        byte[] b = new byte[1024*1024*15];
        System.out.println(m.get());//如果被回收会输出null
    }
}

//软引用非常适合缓存使用
//对象被软引用指向  系统内存不够用了才会回收  系统够用不会回收    内存够用即使GC也不会回收软引用   内存不够清理软引用

弱引用

弱引用遭到gc就会回收

/**
 * 弱引用遭到gc就会回收
 *
 */
import java.lang.ref.WeakReference;

public class T03_WeakReference {
    public static void main(String[] args) {
        WeakReference<M> m = new WeakReference<>(new M());

        System.out.println(m.get());
        System.gc();
        System.out.println(m.get());//弱引用垃圾回收收掉 所以输出null

//弱引用一般用在容器里 如果有另外一个强引用指向她(new M ) 强引用消失 这个就会消失   
        ThreadLocal<M> tl = new ThreadLocal<>();
        tl.set(new M());
        tl.remove();//对象不用了要remove

    }
}


在这里插入图片描述

在这里插入图片描述
ThreadLocalMap在set(k,v)时候,k是ThreadLocal,v是期望的value
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
通过上图可以看出ThreadLocalMap的k是弱引用。
在这里插入图片描述
tl随着方法结束就会指向null,不会再指向ThreadLocal,这个时候如果k指向ThreadLocal是个强引用,ThreadLocal就会内存泄漏,线程不停止都不会回收。所以这个时候K是弱引用,遇到垃圾回收,k指向null,ThreadLocal就会被回收,但是ThreadLocal被回收,value在map,key为null,不会被使用。ThreadLocal调用remove()方法,就会完成清理。

虚引用

一个对象是否有虚引用的存在,完全不会对其生存时间构成影响, 也无法通过虚引用来获取一个对象的实例。
为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
虚引用和弱引用对关联对象的回收都不会产生影响,如果只有虚引用活着弱引用关联着对象, 那么这个对象就会被回收。它们的不同之处在于弱引用的get方法,虚引用的get方法始终返回null,弱引用可以使用ReferenceQueue,虚引用必须配合ReferenceQueue使用。
jdk中直接内存的回收就用到虚引用,由于jvm自动内存管理的范围是堆内存,
而直接内存是在堆内存之外(其实是内存映射文件,自行去理解虚拟内存空间的相关概念), 所以直接内存的分配和回收都是有Unsafe类去操作,java在申请一块直接内存之后,
会在堆内存分配一个对象保存这个堆外内存的引用, 这个对象被垃圾收集器管理,一旦这个对象被回收, 相应的用户线程会收到通知并对直接内存进行清理工作。
事实上,虚引用有一个很重要的用途就是用来做堆外内存的释放, DirectByteBuffer就是通过虚引用来实现堆外内存的释放的。


import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.LinkedList;
import java.util.List;

public class T04_PhantomReference {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();//虚引用回收了 装入队列



    public static void main(String[] args) {


        PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);//只要有垃圾回收就把M干掉


        new Thread(() -> {
            while (true) {
                LIST.add(new byte[1024 * 1024]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());//虚引用拿不到
            }
        }).start();

        new Thread(() -> {
            while (true) {
                Reference<? extends M> poll = QUEUE.poll();
                if (poll != null) {
                    System.out.println("--- 虚引用对象被jvm回收了 ---- " + poll);
                }
            }
        }).start();

        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

//虚引用管理堆外内存  直接内存不会被JVM管理  虚引用被垃圾回收器回收管理堆外内存
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 11:39:48  更:2022-04-28 11:41:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:53:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码