cid#1606940 Check of thread-shared field evades lock acquisition
[LibreOffice.git] / qadevOOo / runner / util / WaitUnreachable.java
blobf90fa6552461d4bb114a164deb4aa036df1c5633
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package util;
21 import java.lang.ref.PhantomReference;
22 import java.lang.ref.ReferenceQueue;
24 /**
25 * Wait until an object has become unreachable.
27 * <p>Instances of this class will typically be used as either:</p>
28 * <pre>
29 * SomeType o = new SomeType(...);
30 * ... // use "o"
31 * WaitUnreachable u = new WaitUnreachable(o);
32 * o = null;
33 * u.waitUnreachable();
34 * </pre>
35 * <p>or:</p>
36 * <pre>
37 * WaitUnreachable u = new WaitUnreachable(new SomeType(...));
38 * ... // use "(SomeType) u.get()"
39 * u.waitUnreachable();
40 * </pre>
42 public final class WaitUnreachable {
43 /**
44 * Creates a new waiter.
46 * @param obj the object on which to wait
48 public WaitUnreachable(Object obj) {
49 this.obj = obj;
50 queue = new ReferenceQueue<Object>();
51 ref = new PhantomReference<Object>(obj, queue);
54 /**
55 * Gets the object on which to wait.
57 * @return the object on which to wait, or <code>null</code> if
58 * <code>waitUnreachable</code> has already been called
60 public synchronized Object get() {
61 return obj;
64 /**
65 * Starts waiting for the object to become unreachable.
67 * <p>This blocks the current thread until the object has become
68 * unreachable.</p>
70 * <p>Actually, this method waits until the JVM has <em>detected</em> that
71 * the object has become unreachable. This is not deterministic, but this
72 * methods makes a best effort to cause the JVM to eventually detect the
73 * situation. With a typical JVM, this should suffice.</p>
75 public void waitUnreachable() {
76 synchronized (this) {
77 obj = null;
79 System.out.println("waiting for gc");
80 while (queue.poll() == null) {
81 System.gc();
82 System.runFinalization();
86 /**
87 * Ensures that an object will be finalized as soon as possible.
89 * <p>This does not block the current thread. Instead, a new thread is
90 * spawned that busy waits for the given object to become unreachable.</p>
92 * <p>This method cannot guarantee that the given object is eventually
93 * finalized, but it makes a best effort. With a typical JVM, this should
94 * suffice.</p>
96 * @param obj the object of which to ensure finalization
98 public static void ensureFinalization(final Object obj) {
99 final class WaitThread extends Thread {
100 private WaitThread(Object obj) {
101 super("ensureFinalization");
102 unreachable = new WaitUnreachable(obj);
105 @Override
106 public void run() {
107 unreachable.waitUnreachable();
110 private final WaitUnreachable unreachable;
112 new WaitThread(obj).start();
115 private Object obj;
116 private final ReferenceQueue<Object> queue;
117 @SuppressWarnings("unused")
118 private final PhantomReference<Object> ref;