精华内容
下载资源
问答
  • 主要介绍了Java引用队列和虚引用,结合实例形式分析了java引用队列和虚引用相关概念、原理与使用方法,需要的朋友可以参考下
  • Java引用队列和虚引用

    千次阅读 2019-06-23 15:50:40
    当联合使用软引用、弱引用和引用队列时,系统在回收被引用的对象之后,将把它所回收对象对应的引用添加到关联的引用队列中。而虚引用在对象被释放之前,将把它对应的虚引用添加到它关联的引用队列中,这使得可以在...

    一 点睛

    引用队列由ReferenceQueue类表示,它用于保存被回收后对象的引用。当联合使用软引用、弱引用和引用队列时,系统在回收被引用的对象之后,将把它所回收对象对应的引用添加到关联的引用队列中。而虚引用在对象被释放之前,将把它对应的虚引用添加到它关联的引用队列中,这使得可以在对象被回收之前采取行动。

    虚引用无法获取它所对应的对象。

    二 实战

    1 代码

    import java.lang.ref.*;
    
    public class PhantomReferenceTest
    {
       public static void main(String[] args)
          throws Exception
       {
          // 创建一个字符串对象
          String str = new String("疯狂Java讲义");
          // 创建一个引用队列
          ReferenceQueue rq = new ReferenceQueue();
          // 创建一个虚引用,让此虚引用引用到"疯狂Java讲义"字符串
          PhantomReference pr = new PhantomReference (str , rq);
          // 切断str引用和"疯狂Java讲义"字符串之间的引用
          str = null;
          // 取出虚引用所引用的对象,并不能通过虚引用获取被引用的对象,所以此处输出null
          System.out.println(pr.get());  //①
          // 强制垃圾回收
          System.gc();
          System.runFinalization();
          // 垃圾回收之后,虚引用将被放入引用队列中
          // 取出引用队列中最先进入队列中的引用与pr进行比较
          System.out.println(rq.poll() == pr);   //②
       }
    }

    2 运行

    null
    true

    3 说明

    使用引用类可以避免在程序执行期间将对象留在内存中。如果以软引用、弱引用或虚引用的方法引用对象,垃圾回收器就能够随意释放对象。如果希望尽可能减小程序在其生命周期中所占用的内存大小,这些引用类很有好处。

    展开全文
  • JAVA 的五种引用类型及引用队列 ​ 在介绍 JAVA 的五种引用之前,先介绍一下什么是引用,以及引用和对象之间的关系 什么是引用 ​ 众所周知,JAVA 是一种面向对象的语言,在 JAVA 程序运行时,对象是存储在堆内存...
  • 主要介绍了Java中管理资源的引用队列相关原理解析,涉及到Java的垃圾回收机制方面的知识,需要的朋友可以参考下
  • 对象的引用被至少一个变量所把持,此时该对象引用就是强引用,jvm无论怎么样都不会回收强引用,除非再也没有任何变量继续把持该引用。 二、软引用、弱引用、虚引用的使用都需要配合SoftReference、WeekReference、...

    参考https://blog.csdn.net/u011936381/article/details/11709245

    一、强引用:

    对象的引用被至少一个变量所把持,此时该对象引用就是强引用,jvm无论怎么样都不会回收强引用,除非再也没有任何变量继续把持该引用。

    二、软引用、弱引用、虚引用的使用都需要配合SoftReference、WeekReference、PhantomReference才能使用。

    这三者的概念:

    软引用:当内存不足时才会回收,其他情况下不会回收。

    弱引用:当垃圾回收期检测到弱引用时会回收,没检测到则不会回收。

    虚引用:随时会回收,一般用于判断虚拟机回收情况,而且必须与引用队列一起用,否则没效果,前面两种可以不与引用队列一起用(最好还是一起用)。

     

    三者使用方式差不多,这里只介绍一种,比如软引用:

    MyObject aRef = new MyObject();

    SoftReference aSoftRef = new SoftReference(aRef); 

    在这个时候,aRef变量还拿着MyObjet对象的引用,此时这引用是强引用,同时该引用还传给了SoftReference 的对象aSoftRef 

    接着执行  aRef =null;

    此时aRef变量没有再把持该引用了,这个时候该对象引用被SoftReference对象aSoftRef 把持着,那就是软引用。

    这个时候MyObjet对象的引用只有当内存不足时才会被垃圾回收器回收。

    另外两种引用使用方式与这差不多。

     

    三、引用队列

     作为一个Java对象,SoftReference对象除了具有保存软引用的特殊性之外,也具有Java对象的一般性。所以,当软可及对象被回收之后,虽然这个SoftReference对象的get()方法返回null,但这个SoftReference对象已经不再具有存在的价值,需要一个适当的清除机制,避免大量SoftReference对象带来的内存泄漏。在java.lang.ref包里还提供了ReferenceQueue。如果在创建SoftReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法,如:

    ReferenceQueue queue = new ReferenceQueue();

    SoftReference ref = new
    SoftReference(aMyObject, queue); 

    那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用的SoftReference对象被列入ReferenceQueue。也就是说,ReferenceQueue中保存的对象是Reference对象,而且是已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
    在任何时候,我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。利用这个方法,我们可以检查哪个SoftReference所软引用的对象已经被回收。于是我们可以把这些失去所软引用的对象的SoftReference对象清除掉。常用的方式为:

    SoftReference ref = null;

    while ((ref = (EmployeeRef) q.poll()) != null) {

    // 清除ref

    }

    展开全文
  • JAVA循环队列

    千次阅读 2017-09-15 15:25:44
    一、JAVA 中已经自带了 Queue、DQueue、ArrayList、LinkedList 等常用的数据结构,为什么还要单独实现循环队列? 之所以使用自定义循环队列,出发点还是基于我们在实际应用中对于数据处理各种各样的需求。使用...

    关于自定义循环队列的实现原理和要点可以参见之前的博文系列:循环队列及C语言实现。这里主要对JAVA下的具体实现方式与原理进行说明。

    一、JAVA 中已经自带了 Queue、DQueue、ArrayList、LinkedList 等常用的数据结构,为什么还要单独实现循环队列?

    之所以使用自定义循环队列,出发点还是基于我们在实际应用中对于数据处理各种各样的需求。使用自定义数据结构的好处就在于可以更加灵活的处理各种数据,增加自己需要的接口。然而弊端就是你的 code 可能会引入各种未知的 Bug。所以,在满足我们使用前提的场景下,使用上述已有数据结构等是比较推荐的,如果满足不了实际项目需求,再通过自定义的方式等实现是我们理想的一种选择。

    二、什么场景需要使用自定义循环队列?

    对于数据的处理要求比较灵活,比如:我们需要开发一个安卓服务器程序,需要不断处理每个客户端的请求以及完成与客户端的交互。发送来的数据需要及时处理,但同时数据以自定义格式进行传输:包头+长度+数据+包尾+校验。如上格式,服务器端需要不断将接收的数据进行缓存与解析,如果未满一帧那么需要缓存到下次数据接收过来再进行解析。这时,我们需要批量从队列读取数据以及如果一帧数据不完全,将读取的数据复原到队列中(更改队列当前读位置)的功能。此时,就可以考虑自己实现队列满足这些特殊的需求。

    三、循环队列的特点与要素

    1、先进先出(FIFO);

    2、队列首尾元素位置;

    3、常用队列操作:初始化、销毁、遍历、读写等;

    四、源码实现

    为便于使用,这里将该循环队列以类的方式实现:

    /*
     * Copyright (c) 2017, SoldierJazz. All rights reserved.
     * Use is subject to license terms.
     *
     */
    
    package com.exmple.java.text;
    
    /**
     * DataQueue 类实现为FIFO循环队列
     *
     * <p> 使用前需要根据实际需求为队列分配合理的队列空间大小
     *
     * 创建一个4K空间的队列如下所示:
     *
     * DataQueue mdataqueue= new DataQueue(4096);
     *
     * <p> 更多使用信息可以参考引用该类的例程,有关问题,可发送到
     * SoldierJazz@163.com 寻求支持。
     *
     * @author      SoldierJazz
     * @version	 1.0.0
     */
    
    public class DataQueue {
    	
    	Queue q = null;
    	
    	public class Queue {
    		byte[] data = null;
    		int read;
    		int write;
    		int size;
    		int space;
    	}
    	
    	Object mSemaphore = new Object();
    	
    	DataQueue(int size) {
    		q = new Queue();
    		Queue_Init(q, size);
    	}
    	
        /**
         * 返回当前队列可用数据量
         *
         * @param    q    目标队列
         *
         */
    	int Avail(Queue q) {
    		return q.size - q.space;
    	}
    	
        /**
         * 初始化队列
         *
         * @param    q    目标队列
         * 
         * @param    size    队列分配内存大小
         *
         */
    	void Queue_Init(Queue q, int size) {
    		synchronized (mSemaphore) {
    			q.data = new byte[size];
    			q.read = 0;
    			q.write = 0;
    			q.size = size;
    			q.space = size;
    		}
    	}
    	
        /**
         * 销毁队列
         *
         * @param    q    目标队列
         *
         */
    	void Queue_Destroy(Queue q) {
    		synchronized (mSemaphore) {
    		    q.read = q.write = 0;
    		    q.space = q.size;
    		}
    	}
    
        /**
         * 判断当前队列是否为空
         *
         * @param    q    目标队列
         *
         * @return    true表示队列为空<br>false表示队列不为空
         *
         */
    	boolean Queue_Empty(Queue q) {
    	    return (q.space == q.size);
    	}
    	
        /**
         * 判断当前队列是否已满
         *
         * @param    q    目标队列
         *
         * @return    true表示队列已满<br>false表示队列未满
         *
         */
    	boolean Queue_Full(Queue q) {
    	    return (q.space == 0);
    	}
    	
        /**
         * 写一个byte到目标队列
         *
         * @param    q    目标队列
         * 
         * @param    val    写入的byte值
         *
         * @return    true表示写入成功<br>false表示写入失败
         *
         */
    	boolean AddQueue(Queue q, byte val) {
    	    if (!Queue_Full(q)) {
    	        q.data[q.write] = val;
    	        q.write = (q.write + 1) % q.size;
    	        q.space--;
    	        return true;
    	    } 
    	    return false;
    	}
    	
        /**
         * 从队列中读取一个字节
         *
         * @param    q    目标队列
         * 
         * @param    data    读取的字节
         *
         * @return    true表示读取成功<br>false表示读取失败
         *
         */
    	boolean DelQueue(Queue q, Byte data) {
    	    if (!Queue_Empty(q)) {
    	        data = q.data[q.read];
    	        
    	        q.read = (q.read + 1) % q.size;
    	        q.space++;
    	        return true;
    	    }
    	    return false;
    	}
    	
        /**
         * 批量写入长度为len的字节到队列
         *
         * @param    q    目标队列
         * 
         * @param    data    写入的byte数组
         * 
         * @param    len    写入的数组长度
         *
         * @return    成功写入的字节数量
         *
         */
    	int WriteQueue(Queue q, byte[] data, int len)
    	{
    	    int ret = 0;
    	    int rest = q.size - q.write;
    
    	    synchronized (mSemaphore) {
    		    if (!Queue_Full(q)) {
    		        if (q.space >= len) {
    		            ret = len;
    		            if (rest >= len) {
    		                System.arraycopy(data, 0, q.data, q.write, len);
    		                q.write = (q.write + len) % q.size;
    		                q.space -= len;
    		            } else {
    		                System.arraycopy(data, 0, q.data, q.write, rest);
    		                q.write = 0;
    		                System.arraycopy(data, rest, q.data, 0, len - rest);
    		                q.write = len -rest;
    		                q.space -= len;
    		            }
    		        } else {
    		            ret = q.space;
    		            if (rest >= q.space) {
    		                System.arraycopy(data, 0, q.data, q.write, q.space);
    		                q.write = (q.write + q.space) % q.size;
    		                q.space = 0;
    		            } else {
    		                System.arraycopy(data, 0, q.data, q.write, rest);
    		                q.write = 0;
    		                System.arraycopy(data, rest, q.data, 0, q.space - rest);
    		                q.write = q.space -rest;
    		                q.space = 0;
    		            }
    		        }   
    		    }
    		    return ret;
    	    }
    	}
    	
        /**
         * 从队列中恢复长度len个字节的数据
         *
         * @param    q    目标队列
         * 
         * @param    len    要恢复的长度
         *
         * @return    成功恢复的字节数
         *
         */
    	int RecoverReadQueue(Queue q, int len) {
    	    int ret = 0;
    	    int rest = q.read;
    
    	    synchronized (mSemaphore) {
    	    	
    	    	if (q.space >= len)
    	    		ret = len;
    	    	else
    	    		ret = q.space;
    	    	
    		    if (rest >= ret) {
    		        q.read -= ret;
    		    } else {
    		        q.read = q.size - (ret - rest);
    		    }
    		    q.space -= ret;
    	
    		    return ret;
    	    }
    	}
    	
        /**
         * 从队列中读取len个字节数据到data数组中
         *
         * @param    q    目标队列
         * 
         * @param    data    用于存放数据的目标数组
         * 
         * @param    start    拷贝至目标数组的起始位置
         * 
         * @param    len    读取的长度
         * 
         * @return    成功读取的字节数
         *
         */
    	int ReadQueue(Queue q, byte[] data, int start, int len) {
    	    int rest = q.size - q.read;
    	    int ret = 0;
    
    	    synchronized (mSemaphore) {
    		    if (!Queue_Empty(q)) {
    		        if (Avail(q) >= len) {
    		            ret = len;
    		            if (rest >= len) {
    		                System.arraycopy(q.data, q.read, data, start, len);
    		                q.read = (q.read + len) % q.size;
    		                q.space += len;
    		            } else {
    		                System.arraycopy(q.data, q.read, data, start, rest);
    		                q.read = 0;
    		                System.arraycopy(q.data, 0, data, start + rest, len - rest);
    		                q.read = len -rest;
    		                q.space += len;
    		            }
    		            return len;
    		        } else {
    		            ret = Avail(q);
    		            if (rest >= Avail(q)) {
    		                System.arraycopy(q.data, q.read, data, start, Avail(q));
    		                q.read = (q.read + Avail(q)) % q.size;
    		                q.space = q.size;
    		            } else {
    		                System.arraycopy(q.data, q.read, data, start, rest);
    		                q.read = 0;
    		                System.arraycopy(q.data, 0, data, start + rest, Avail(q) - rest);
    		                q.read = Avail(q) -rest;
    		                q.space = q.size;
    		            }
    		        }
    		    } 
    		    return ret;
    	    }
    	}
    }
    以上内容为使用该类及相关方法的定义,比较简单,看注解即可。下面针对该类做一个使用与测试程序:

    	public void TestDataQueue() {
    		DataQueue dataq = new DataQueue(100);
    		byte[] a1 = {1, 2, 3, 4, 5, 6};
    		byte[] a2 = {7, 8, 9, 10};
    		byte[] b = new byte[10];
    		int nread = 0;
    		dataq.WriteQueue(dataq.q, a1, a1.length);
    		nread = dataq.ReadQueue(dataq.q, b, 0, 3);
    		System.out.println("length of queue: " + dataq.Avail(dataq.q));
    		for (int i = 0; i < nread; i++) {
    			System.out.printf("byte[%d]: %d\n", i, b[i]);
    		}
    		dataq.WriteQueue(dataq.q, a2, a2.length);
    		System.out.println("length of queue: " + dataq.Avail(dataq.q));
    		nread = dataq.ReadQueue(dataq.q, b, 0, dataq.Avail(dataq.q));
    		System.out.println("length of queue: " + dataq.Avail(dataq.q));
    		for (int i = 0; i < nread; i++) {
    			System.out.printf("byte[%d]: %d\n", i, b[i]);
    		}
    	}
    	
    	public static void main(String args[]) {
    		test t = new test();
    		t.TestDataQueue();
    	}
    运行结果如下所示:



    有疑问或者问题就给我邮件或者评论吧,觉得有用就点赞吧~:-D



    展开全文
  • 目录 强引用引用引用 幻象引用 Reachability Fence 参考 强引用 正常的引用,生命周期最长,例如 Object obj = new Object(); 当JVM内存不足时,宁可抛出OutOfMemor...

    强引用

    正常的引用,生命周期最长,例如 Object obj = new Object(); 当JVM内存不足时,宁可抛出OutOfMemoryError,也不愿回收存活着强引用的对象

    对象还活着吗?当一个普通对象没有其他引用关系,只要超过了引用的作用域或者显示的将引用赋值为null时,你的对象就表明不是存活着,这样就会可以被GC回收了。

    软引用

    生命周期比强引用短,通过SoftReference类实现,可以通过get方法获取对象。
    A

    1488206-20200310105413349-1946312875.png

    当JVM内存不足时会先回收软引用指向的对象,即抛出OutOfMemoryError之前,会去清理软引用对象。

    软引用通常会在最后一次引用后,还能保持一段时间,默认值是根据堆剩余空间计算的。

    如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用 队列中。软引用可以和引用队列(referenceQueue)联用,我们可以调用ReferenceQueue的poll()方法来检查是否有它所关心的对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。

    1488206-20200310105436135-553750826.png

    应用场景:软引用一般用来实现内存敏感的缓存,如果有空闲内存就可以保留缓存,当内存不足时就清理掉,这样就保证使用缓存的同时不会耗尽内存,如图片缓存框架中缓存图片就是通过软引用实现。

    弱引用

    弱引用是通过WeakReference类实现的,它的生命周期比软引用还要短,也是通过get()方法获取对象。

    1488206-20200310105454306-317826854.png

    JVM内存回收时,不论是否内存不足,都会回收弱引用的对象。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快回收弱引用的对象。

    弱引用可以配合引用队列,如果弱引用所引用的对象被垃圾 回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

    应用场景:弱引用适用于内存敏感的缓存,如ThreadLocal中的key就用到了弱引用。

    幻象引用

    通过PhantomReference类实现,任何时候都可以被回收,可以看作没有引用。必须和引用队列联用。无法通过get方法获取对象。

    幻象引用仅仅是提供了一种确保对象被 fnalize 以后,做某些事情的机制。当垃圾回收器准备回收一个对象时,如 果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之 前采取一些程序行动。

    应用场景:可用来跟踪对象被垃圾回收器回收的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知。

    
    Object counter = new Object();
    ReferenceQueue refQueue = new ReferenceQueue<>();
    PhantomReference<Object> p = new PhantomReference<>(counter, refQueue);
    counter = null;
    Sysem.gc();
    try {
     // Remove是一个阻塞方法,可以指定timeout,或者选择一直阻塞
     Reference<Object> ref = refQueue.remove(1000L);
     if (ref != null) {
     // do something
     }
    } catch (InterruptedException e) {
     // Handle it
    }

    Reachability Fence

    按照Java语言规范,如果一个对象没有指向强引用,就符合垃圾收集的标准。但有的场景中,对象本身并没有强引用,但是也许它的部分属性还在被使用。为了防止对象被回收,我们需要一个方法,在没有强引用情况下,通知JVM对象是在被使用的。

    Java9之后,java.lang.ref.Reference给我们提供了一种方法, reachabilityFence,来声明某些没有强引用的对象,依然强可达。编程时,可以将需要reachability保障的代码段利用try-fnally包围起来,在finally里明确声明对象强可达

    
    class Resource {
     private satic ExternalResource[] externalResourceArray = ...
     int myIndex; Resource(...) {
     myIndex = ...
     externalResourceArray[myIndex] = ...;
     ...
     }
     protected void fnalize() {
     externalResourceArray[myIndex] = null;
     ...
     }
     public void action() {
     try {
     // 需要被保护的代码
     int i = myIndex;
     Resource.update(externalResourceArray[i]);
     } fnally {
     // 调用reachbilityFence,明确保障对象srongly reachable
     Reference.reachabilityFence(this);
     }
     }
     private static void update(ExternalResource ext) {
     ext.status = ...;
     }
    }
    
    //非强引用
    new Resource().action()

    在JDK源码中,reachabilityFence大多使用在Executors或者类似新的HTTP/2客户端代码中,大部分都是异步调用的情况。

    参考

    《深入理解Java虚拟机》周志明
    《Java核心技术36讲》杨晓峰
    https://baijiahao.baidu.com/s?id=1629253892215446066&wfr=spider&for=pc

    展开全文
  • 解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程池问题,我相信很多人都一知半解的,包括我自己在仔仔细细看源码之前,也有...
  • 四种引用类型及引用队列

    千次阅读 2017-11-23 18:17:00
    本文目录 1 强引用(StrongReference) 2 软引用(SoftReference) ...5 引用队列(ReferenceQueue) 1 强引用(StrongReference) 效果:存在强引用的对象,不会被JVM回收。 // 强引用 String str = n...
  • 之前写过一篇博客,关于非堆内存如何自动释放的,由此慢慢延伸写了几篇关于垃圾回收、finalize机制、引用和引用队列、sun.misc.Cleaner相关的文章,通过这几篇文章感觉自己收获很大了,对java垃圾回收相关的知识了解...
  • 上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文章来了解剩下的四种阻塞队列。读完本文你将了解:七种阻塞队列的后四种 ...
  • 什么是引用队列当创建一个非强引用的引用对象时,可以传一个引用队列对象给Reference构造函数。引用队列作为GC通知程序某个对象不可达的信号,引用队列装载这个不可达对象引用的容器。
  • 下面小编就为大家带来一篇关于finalize机制和引用、引用队列的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Java队列实现

    万次阅读 多人点赞 2017-09-19 11:42:26
    一、队列简单介绍队列是一种常用的数据结构之一,与之前的栈类似,不过队列是“先进先出”。队列有队头(front)和队尾(rear),数据从队尾进入队列,从队头出队列,队头(front)指向队列的第一个数据,队尾(rear...
  • java 阻塞队列BlockingQueue

    千次阅读 2014-11-30 16:49:38
    开发中如果队列的插入操作比较频繁建议使用LinkedBlockingQueue,因为每个node节点都有一个前后指针,插入新元素仅需要变更前后的指针引用即可, ArrayBlockingQueue插入新元素,则新元素之后的元素数组下标位置都要...
  • JAVA双向队列实现(链表)

    千次阅读 2018-10-20 09:40:40
    队列是很常见的一种数据存储结构,今天,介绍下如何用链表实现双向队列。 首先定义节点接口如下: public interface Node&lt;E&gt; { //设置数据元素 public void setData(E o); //获取节点元素 public ...
  • 文章目录1.队列的基本介绍2.队列的基本用法3.实例 1.队列的基本介绍 队列是数据结构中比较重要的一种类型(是一种数据结构),它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟...import java.util.Queu
  • Java无锁队列与栈的实现

    千次阅读 2014-01-16 15:43:50
     尽管这篇文章讲的是无锁队列,但是引用Java并发实践》中的一句话,并发环境下,首先应该保证正确性,其次才是性能。在没有证明现情况下性能确实需要提高,且锁机制无法满足的时候,才应该考虑无锁。确实,无锁...
  • Java引用类型

    千次阅读 2018-09-04 14:31:34
    Java引用类型的知识点详解。 引用类型:强引用、软引用、弱引用、虚引用 对像生命周期和可达性状态 引用队列 reachability fench(可达性栏杆) 引用类型 版本:2018/9/4-1(13:13) 引用类型 面试题 引用...
  • java 中 阻塞队列 非阻塞队列 和普通队列的区别

    万次阅读 热门讨论 2018-08-22 23:14:26
    阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列...
  • priorityQueue是Java封装的优先无界队列,它基于的是优先级堆。 对于基本数据类型默认小顶堆,对于引用类型基于的是Comparator接口。 如果引用类型没有基于Comparator接口的外比较器,则会报错。 构造方法 public ...
  • C++有析构函数这个东西,能够很好地在对象销毁前做一些释放外部资源的工作,但是java没有。Object.finalize()提供了与析构函数类似的机制,但是它不安全、会导致严重的内存消耗和性能降低,应该避免使用。best ...
  • java队列实现(顺序队列、链式队列、循环队列

    万次阅读 多人点赞 2014-01-21 15:45:31
    1.顺序队列的实现 package lang; import java.io.Serializable; import java.util.Arrays; /** * @ClassName: ArrayQueue * @Description: 顺序队列 * @date 2014年1月20日 下午3:46:19 * @param */ public ...
  • java 队列和栈

    千次阅读 2013-10-23 09:43:35
    栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。 LinkedList数据结构是一种双向的链式结构,每一个对象除了数据本身外,还有两个...
  • Java线程安全队列Queue

    千次阅读 2017-06-05 17:06:12
    Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,786
精华内容 55,114
关键字:

java引用队列

java 订阅