sun.misc.Cleaner源码解析

前请先看《一提到Reference 99.99%的java程序员都懵逼了》,否则里面的讲解会看不懂!弄懂了Reference看下我写的注释就轻松明白Cleaner原理

Cleaner源码解析

 

/*

 * Copyright (c) 2003, 2013, Oracle and/or itsaffiliates. All rights reserved.

 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES ORTHIS FILE HEADER.

 *

 * This code is free software; you canredistribute it and/or modify it

 * under the terms of the GNU General PublicLicense version 2 only, as

 * published by the Free SoftwareFoundation.  Oracle designates this

 * particular file as subject to the "Classpath"exception as provided

 * by Oracle in the LICENSE file thataccompanied this code.

 *

 * This code is distributed in the hope that itwill be useful, but WITHOUT

 * ANY WARRANTY; without even the impliedwarranty of MERCHANTABILITY or

 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License

 * version 2 for more details (a copy isincluded in the LICENSE file that

 * accompanied this code).

 *

 * You should have received a copy of the GNUGeneral Public License version

 * 2 along with this work; if not, write to theFree Software Foundation,

 * Inc., 51 Franklin St, FifthFloor, Boston, MA 02110-1301 USA.

 *

 * Please contact Oracle, 500 Oracle Parkway,Redwood Shores, CA 94065 USA

 * or visit www.oracle.com if you needadditional information or have any

 * questions.

 */

 

packagesun.misc;

 

import java.lang.ref.*;

import java.security.AccessController;

import java.security.PrivilegedAction;

 

 

/**

 * General-purpose phantom-reference-based cleaners.

 *

 * <p> Cleaners are a lightweight and more robust alternativeto finalization.

 * They are lightweight because they are notcreated by the VM and thus do not

 * require a JNI upcall to be created,and because their cleanup code is

 * invoked directly by the reference-handler thread ratherthan by the

 * finalizer thread.  They are more robust because they use phantomreferences,

 * the weakest type of reference object,thereby avoiding the nasty ordering

 * problems inherent to finalization.

 *

 * <p> A cleaner tracks a referent object and encapsulates athunkof arbitrary

 * cleanup code.  Some time after the GC detects that acleaner's referent has

 * become phantom-reachable, the reference-handler thread willrun the cleaner.

 * Cleaners may also be invoked directly; theyare thread safe and ensure that

 * they run their thunks at most once.

 *

 * <p> Cleaners are not a replacement for finalization.  They should be used

 * only when the cleanup code is extremelysimple and straightforward.

 * Nontrivial cleaners are inadvisable sincethey risk blocking the

 * reference-handler thread and delaying further cleanupand finalization.

 *

 *

 * @author MarkReinhold

 */

//继承自PhantomReference

publicclassCleaner

   extendsPhantomReference<Object>

{

 

   // Dummy reference queue, needed becausethe PhantomReference constructor

   // insists that we pass a queue.  Nothing will ever be placed on this queue

   // since the reference handler invokescleaners explicitly.

    //Cleaner引用的ReferenceQueue队列,静态全局变量,如果你看过ReferenceHander线程的处理过程,就会知道,Cleaner对象经过ReferenceHander线程处理后是不会进入这个队列的,设置它是为了让Cleaner对象进入到pending队列,能够被ReferenceHander线程处理到,没有设置队列的Reference对象gc时会直接变为nactive状态,不会进入pending队列,详情看我的另外一篇文章《一提到Reference 99.99%的java程序员都懵逼了》中关于Reference对象的状态转换

   privatestaticfinalReferenceQueue<Object>dummyQueue =newReferenceQueue<>();

 

   // Doubly-linked list of live cleaners,which prevents the cleaners

   // themselves from being GC'd before theirreferents

    // first变量与next、prev变量一起构建一个双向链表, 我给它起了个名字叫unClean队列,first是队列的头部,静态变量,所以进入这个队列的对象都不会被回收,Cleaner对象创建的时候会加入这个链表,回收之前会先从这个链表中被移除,出队入队操作都是在队列头部,所以太是一个后进先出队列,unClean队列的作用是保持对Cleaner对象的强引用,防止Cleaner对象在它引用的对象之前被垃圾回收器回收掉;

   staticprivate Cleanerfirst =null;

 

   privateCleaner

        next =null,

        prev =null;

  

   //unClean队列入队操作 ,加入到队列头部

  privatestaticsynchronized Cleaneradd(Cleanercl) {

        if (first !=null) {

            cl.next =first;

            first.prev =cl;

        }

        first =cl;

        returncl;

   }

    //unclean队列的出队操作,从头部出队

   privatestaticsynchronizedboolean remove(Cleaner cl) {

 

        // If already removed, do nothing

        if (cl.next==cl)

            returnfalse;

 

        // Update list

        if (first ==cl) {

            if (cl.next!=null)

                first =cl.next;

            else

                first =cl.prev;

        }

        if (cl.next!=null)

            cl.next.prev=cl.prev;

        if (cl.prev!=null)

            cl.prev.next=cl.next;

 

        // Indicate removal by pointing the cleaner to itself

        cl.next =cl;

        cl.prev =cl;

        returntrue;

 

   }

    //实现Runable接口的对象,这个对象会在实现的run方法里做gc前清理资源的操作,它的run方法最终会由ReferenceHander线程来调用执行

   privatefinal Runnablethunk;

    //私有的构造方法,说明Cleaner对象是无法直接被创建的,参数为被引用的对象和ReferenceQueue成员变量

   privateCleaner(Objectreferent,Runnablethunk){

        super(referent,dummyQueue);

        this.thunk =thunk;

   }

   

    //这个create静态方法提供给我们来实例化Cleaner对象,需要两个参数,被引用的对象与实现了Runnable接口的对象,新创建的Cleaner对象被加入到了unclean队列里

   /**

     * Creates a new cleaner.

     *

     * @param  obthe referent object to be cleaned

     * @param thunk

     *        The cleanup code to be run when the cleaner is invoked.  The

     *        cleanup code is run directly from the reference-handler thread,

     *        so it should be as simple and straightforward as possible.

     *

     * @return The new cleaner

     */

   publicstatic Cleaner create(Objectob, Runnable thunk) {

        if (thunk ==null)

            returnnull;

        returnadd(new Cleaner(ob,thunk));

   }

    //clean方法先将对象从unclean队列移除(这样Cleaner对象就可以被gc回收掉了),然后调用thunk的run方法执行清理操作

   /**

     * Runs this cleaner, if it has not beenrun before.

     */

   publicvoid clean() {

        if (!remove(this))

            return;

        try {

            thunk.run();

        } catch (final Throwablex) {

            AccessController.doPrivileged(newPrivilegedAction<Void>() {

                    public Void run() {

                        if (System.err != null)

                            new Error("Cleaner terminated abnormally",x)

                               .printStackTrace();

                        System.exit(1);

                        returnnull;

                    }});

        }

   }

 

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值