Java隐式定义对类中使用的对象的引用是真的吗?

时间:2011-10-25 04:46:27

标签: java reference

在阅读书籍后,浏览关于Java中引用类型的网络,我仍有一些疑问(或者我可能将这个概念解释错了)。
如果有人明白我的疑虑,对我来说将是一个很大的帮助。

让我举一个包含类变量,实例变量和局部变量的类的例子。

public class Test {
  public static ArrayList<String> listCommon = new ArrayList<String>();
  private HashMap<String, String> mapInstance;

  public Test() {
    mapInstance = new HashMap<String, String>();
  }

  public void doSomething(String key) {
    ArrayList<String> local = new ArrayList<String>();
    if(key != null){
      local.add(mapInstance.get(key));
    }

    System.out.println("Value is added in instance Map: ", mapInstance.get(key));
  }
}

我的问题是;
1.是listCommon(静态变量)和mapInstance(实例变量)对垃圾收集器的强引用?
2.变量local(在方法中定义和使用)是弱引用吗?
3. Phantom参考和Soft参考如何出现在图片中? 4.或以上3个概念无效;是否只有在显式使用java.lang.ref包中定义的类型时,Java才定义引用?

任何帮助对我来说都很棒。

3 个答案:

答案 0 :(得分:11)

  
      
  1. 是listCommon(静态变量)和mapInstance(实例变量)对垃圾收集器的强引用?
  2.   

他们是强有力的参考,是的。

  
      
  1. 变量local(在方法中定义和使用)是弱引用吗?
  2.   

不,它是一个局部变量,因此它是一个变量,因此它仍然是一个强大的参考。

  
      
  1. Phantom参考和Soft参考如何进入图片?
  2.   

如果你使用它们。如果您不使用它们,则无需担心它们。它们用于编写各种缓存。

  
      
  1. 或以上3个概念无效;表示只有在您明确使用了中定义的类型时,Java才定义引用   java.lang.ref包?
  2.   

参考变量总是很强大。只有在明确使用它们时才会出现其他类型。

答案 1 :(得分:4)

阅读有关变量引用的this博文。

** 更新 **

原子引用是以这样的方式引用的对象,它以原子方式访问;意味着没有竞争条件访问它。例如:

class RaceTest {
   static private int count = 0;
   static public void main(String...args) {
      Thread t1 = new Thread(new Runnable() {
         public void run() {
             for (int i=0; i<1000000; i++) {
                 count++;
             }
      });
      Thread t2 = new Thread(new Runnable() {
         public void run() {
             for (int i=0; i<1000000; i++) {
                 count--;
             }
         }
      });

      t1.start();
      t2.start();

      t1.join();
      t2.join();

      System.out.println("Final count (should be 0) = " + count);
   }
}

将生成两个线程,1)将递增count,2)将递减它。现在,两个线程将并行运行,程序将一直等到两个终止(在join点)。一个常见的想法是,由于两个线程都具有相同的循环(将循环相同的时间量),每个线程将“取消”彼此的操作,因此count应为0,但事实并非如此。为什么?例如,虽然t1可能希望增加变量,但此类操作不是原子操作,而是更多的顺序为:getincset。因此,可能存在这样的情况:即使在第二次操作inc之前,t2也会访问变量并dec变量,因此t1实际上会{ {1}}变量。反之亦然。 (每次运行代码都会产生不同的值。)

现在,将+2替换为int并使用AtomicIntegerincrementAndGet()将通过呈现decrementAndGet()get,{来解决此问题{1}}进入单个操作,并消除代码中的竞争条件。

答案 2 :(得分:4)

回答问题:

  1. 是的,它们是强有力的参考。使用Weak reference对象定义弱引用。

  2. 不,原因为1)。

  3. Phantom Reference并不适用于您的示例。默认情况下,所有实例都是强引用。

  4. 是的,您使用java.lang.ref包指定了弱/幻像引用。默认情况下,使用强引用。

  5. 注意:维基百科对Weak Reference的解释可能有用。