Демонстрационный код:
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
Object test = new Object();
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
PhantomReference<Object> p = new PhantomReference<Object>(test, q);
Object lock = new Object();
while (true) {
synchronized (lock) {
//q.poll() is null always,why?
if (q.poll() != null) {
break;
}
//System.gc();
lock.wait();
}
}
System.out.println(1111111);
}
}
Я тестировал код, но он всегда тупиковый.Код (System.out.println (1111111);) не может быть выполнен, q.poll () возвращает ноль.
Я думаю, если тестовый объект будет удален с помощью GC, q.poll () вернет объект p, затем прервите цикл, но вызовите этот демонстрационный код, это не похоже на мою мысль
Отредактировано: я изменяю демонстрационный код, теперь он может работать.
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
Object test = new Object();
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
PhantomReference<Object> p = new PhantomReference<Object>(test, q);
Object lock = new Object();
while (true) {
synchronized (lock) {
if (q.poll() != null) {
break;
}
test = null; //it is important
System.gc();
lock.wait(100);//should not lock.wait()
}
}
System.out.println(1111111);
}
}
Как говорит sb,оператор (test = null) является key.GC собирает тестовый объект, которому присваивается значение null.