关于JAVA引用【软引用,虚引用】 Reference 和 ReferenceQueue 使用的完整实例代码

说是原创吧,但是也是看别人的内容进行学习的,说不是原创吧,全部的代码是自己手敲了一遍,姑且认为是原创,会贴出所有参考过的帖子。


如果需要了解完整的原理,源码讲解,请查看以下的代码内容,博主讲的很详细了。
  1. Reference和ReferenceQueue深入解读
  2. 你不可不知的Java引用类型之——ReferenceQueue源码详解

整理内容后心得和总结

内容提供给大家参考,如有不当请指出。尽量尽快修改
    1、ReferenceQueue是检测被回收的内容的队列,请阅读上文的原理,便可得知,只有被回收的对象才会到此处
    2、Reference是标记或者包装内容的对象
    3、Reference的继承类有WeakReference(弱引用),软引用SoftReference,虚引用PhantomReference,保底引用FinalReference
    4、强引用是默认,没有继承类
         其中 保底引用FinalReference 是管理其他非自动释放的资源的(未尝试)
    5、包装后的数据,按照正常的使用方式进行使用,按照gc的回收规则,引用的内容会进行具体的操作
    6、正常的使用类,list,map之类的,使用上都是一样,不过需要提前判断当前的内容是否已经被回收掉了。
    7、包装的过程Reference<包装对象类名称> ref = new WeakReference<包装对象类名称>( 包装对象内容, ReferenceQueue队列实例 );
    8、检测是否被回收的内容 从ReferenceQueue队列实例中检测看内容是否还存在
         while((reff=( Reference< char[] > ) queue.remove())!=null) {}

完整的代码如下:

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class CReferenceText
{
   private static int sizeNum = 1024*1024;

   public static void main( String[] args )
   {
      
      /**
       * 定义获取内容的队列
       * ReferenceQueue是检测被回收的内容
       * Reference是标记的对象,
       * Reference的继承类有WeakReference(弱引用),软引用SoftReference,虚引用PhantomReference,保底引用FinalReference
       * @其中 保底引用FinalReference 是管理其他非自动释放的资源的
       * 包装后的数据,按照正常的使用方式进行使用,按照gc的回收规则,引用的内容会进行具体的操作
       * 正常的使用类,list,map之类的,使用上都是一样,不过需要提前判断当前的内容是否已经被回收掉了。
       * 包装的过程Reference<包装对象类名称> ref = new WeakReference<包装对象类名称>( 包装对象内容, ReferenceQueue队列实例 );
       * 检测是否被回收的内容 从ReferenceQueue队列实例中检测看内容是否还存在
       * while((reff=( Reference< char[] > ) queue.remove())!=null) 
       */
       // map 内容测试
//      mapTest();
		// list 内容测试
      listTest();
      
   }
   private static void listTest() {
      ReferenceQueue< char[]  > queue = new ReferenceQueue<char[] >();
      List<Reference<char[]>> list = new ArrayList<>();
   // 定义守护线程
      Thread thread = new Thread(new Runnable()
      {
         @Override
         public void run()
         {
            Reference<char[]> reff;
            try
            {
            	// 检测是否已经被回收了
               while((reff=( Reference< char[] > ) queue.remove())!=null) {
                  System.out.println( "回收数据"+ reff );
               }
            }
            catch ( InterruptedException e )
            {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      });
      // 设置守护线程
      thread.setDaemon( true );
      thread.start();
      
      for(int i=0;i<1000;i++) {
         char[] c = new char[sizeNum];
         // 封装或者转换或者包装对象,包装之后为指定内容的数据
         Reference<char[]> ref = new WeakReference< char[] >( c, queue );
         list.add( ref );
      }
      System.out.println( "内容写入完成,目前大小为:" + list.size() );
      int liveNum = 0;
      int len = list.size();
      for(int i=0;i<len;i++) {
         Reference<char[]> ref = list.get( i );
         if(null != ref && null!=ref.get()) {
            liveNum++;
         }
      }
      System.out.println( "存活数量内容"+liveNum );
   }
   
   private static void mapTest() {
      ReferenceQueue< char[]  > queue = new ReferenceQueue<char[] >();
      // 定义存储的map对象
      Map<String,Reference<char[]>> map = new HashMap< String,Reference<char[]>>();
      // 定义守护线程
      Thread thread = new Thread(new Runnable()
      {
         @Override
         public void run()
         {
            Reference<char[]> reff;
            try
            {
            	// 检测是否已经被回收了
               while((reff=( Reference< char[] > ) queue.remove())!=null) {
                  System.out.println( "回收数据"+ reff );
               }
            }
            catch ( InterruptedException e )
            {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      });
      // 设置守护线程
      thread.setDaemon( true );
      thread.start();
      
      // 定义持续性的增加加入内容
      for(int i=0;i<1000;i++) {
         String key = UUID.randomUUID().toString();
         char[] c = new char[sizeNum];
         // 封装或者转换或者包装对象,包装之后为指定内容的数据
         Reference<char[] > ref = new WeakReference< char[]  >( c, queue );
         map.put( key ,ref );
      }
      System.out.println( "写入内容完成,目前map内容大小->" + map.size() );
      
      int liveNum = 0;
      for(Map.Entry<String,Reference<char[]>> entry:map.entrySet()) {
         if(null!=entry && null!=entry.getKey() && null!=entry.getValue() && null!=entry.getValue().get()) {
            liveNum++;
         }
      }
      
      System.out.println( "存活个数->" + liveNum );
   }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值