Package java. Lang. Ref;
Import java. Security. privilegedaction;
Import java. Security. accesscontroller;
// Comment by liqiang
Final class finalizer extends finalreference {// class used in the package
/*
* A local method is used to call the Finalize method of any object, because the Finalize method of the object
* It is protected and cannot be called directly.
*/
Static native void invokefinalizemethod (Object O) throws throwable;
// Reference the queue, Which is static
Static private referencequeue queue = new referencequeue ();
Static private finalizer unfinalized = NULL;
// Lock Object
Static private object lock = new object ();
// The previous object and the next object of the object. The queue uses two-way
Private finalizer
Next = NULL,
Prev = NULL;
// Whether to finalize
Private Boolean hasbeenfinalized (){
Return (next = This );
}
Private void add (){
Synchronized (LOCK ){
If (unfinalized! = NULL ){
// Add the current object before unfinalized if unfinalized is not null
This. Next = unfinalized;
Unfinalized. Prev = this;
}
// Set unfinalized to the current object
Unfinalized = this;
}
}
// Team out
Private void remove (){
Synchronized (LOCK ){
If (unfinalized = This ){
If (this. Next! = NULL ){
Unfinalized = This. Next;
} Else {
Unfinalized = This. Prev;
}
}
// Retrieve this
If (this. Next! = NULL ){
This. Next. Prev = This. Prev;
}
If (this. Prev! = NULL ){
This. Prev. Next = This. Next;
}
// Set the next and Prev values of the current object to the current object.
This. Next = this;
This. Prev = this;
}
}
// Finalizee is referent
Private finalizer (Object finalizee ){
Super (finalizee, queue );
Add ();
}
// Called by a virtual machine
Static void register (Object finalizee ){
// The queue is static, so the constructed state administration is directly added to the peer Column
New finalizer (finalizee );
}
// Call the Finalize method of the encapsulated object
Private void runfinalizer (){
Synchronized (this ){
If (hasbeenfinalized () return;
Remove ();
}
Try {
// Read the referenced object encapsulated by the current object
Object finalizee = this. Get ();
If (finalizee! = NULL ){
// Call the Finalize method of the encapsulated object
Invokefinalizemethod (finalizee );
Finalizee = NULL;
}
} Catch (throwable X ){}
Super. Clear ();
}
Private Static void forksecondaryfinalizer (final runnable proc ){
Privilegedaction Pa = new privilegedaction (){
Public object run (){
Threadgroup Tg = thread. currentthread (). getthreadgroup ();
For (threadgroup tgn = Tg;
Tgn! = NULL;
Tg = tgn, tgn = Tg. getparent ());
Thread SFT = new thread (TG, Proc, "secondary finalizer ");
SFT. Start ();
Try {
SFT. Join ();
} Catch (interruptedexception X ){
/* Ignore */
}
Return NULL;
}};
Accesscontroller. doprivileged (PA );
}
// Called by the runtime. runfinalization () method
Static void runfinalization (){
Forksecondaryfinalizer (New runnable (){
Public void run (){
For (;;){
// Team out
Finalizer F = (finalizer) queue. Poll ();
If (F = NULL) break;
// Call the Finalize method of the encapsulated object
F. runfinalizer ();
}
}
});
}
// Called by Java. Lang. Shutdown
// Call the Finalize method that strongly references all objects in the list represented by unfinalized
Static void runallfinalizers (){
Forksecondaryfinalizer (New runnable (){
Public void run (){
For (;;){
Finalizer F;
Synchronized (LOCK ){
F = unfinalized;
If (F = NULL) break;
Unfinalized = f. Next;
}
F. runfinalizer ();
}}});
}
// An internal class inherited from the thread
Private Static class finalizerthread extends thread {
Finalizerthread (threadgroup g ){
Super (G, "finalizer ");
}
Public void run (){
For (;) {// call the remvoe method of the queue repeatedly to obtain the object and call the corresponding runfinalizer method.
Try {
Finalizer F = (finalizer) queue. Remove ();
F. runfinalizer ();
} Catch (interruptedexception X ){
Continue;
}
}
}
}
Static {
// Obtain the current thread group
Threadgroup Tg = thread. currentthread (). getthreadgroup ();
// Obtain the system thread group
For (threadgroup tgn = Tg;
Tgn! = NULL;
Tg = tgn, tgn = Tg. getparent ());
// Start the thread
Thread finalizer = new finalizerthread (TG );
Finalizer. setpriority (thread. max_priority-2 );
Finalizer. setdaemon (true );
Finalizer. Start ();
}
}