关于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 );
   }

}

猜你喜欢

转载自blog.csdn.net/u011008832/article/details/113613708