如何在 java 中重新创建单例 class
how can I recreate singleton class in java
我以为我写对了,但我没有找到错误的地方。
我创建了一个单身人士 class(使用 apache commons 的环形缓冲区);这在 mainactivity 和 guimanager 中使用(都是我的实现) - 因此 ringbuffer 的单例 class。以上 classes 通过调用
获取单例的引用
RingBuffer.getInstance()
在某些时候,用户想要更改环形缓冲区的大小,因此我通过调用
重新创建单例 class
RingBuffer.recreateRingBuffer()
问题:在重新创建单例实例后 class,我希望 mainactivity 和 guimanager 中的现有引用将自动修改为新引用(不同大小的 ringbuffer)。但是不,我仍然有旧的参考(旧尺寸的缓冲区)。换句话说,如何在修改引用时自动修改 getInstance() 的 return 值(因此调用方方法和 ringbuffer 在对象的同一副本上工作)
这是我的单身人士class
import java.util.Arrays;
import org.apache.commons.collections.buffer.CircularFifoBuffer;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.math3.stat.StatUtils;
import android.util.Log;
public class RingBuffer {
private CircularFifoBuffer buffer;
private int size;
private volatile static /*final*/ RingBuffer instance = new RingBuffer(7);
private RingBuffer(int n) {
size = n;
buffer = new CircularFifoBuffer(size);
}
public static RingBuffer getInstance() {
return instance;
}
public static RingBuffer recreateRingBuffer(int n) {
Log.e(Constants.GLOBALTAG,"Recreating RingBuffer of Size "+n);
instance=null;
instance=new RingBuffer(n);
return instance;
}
}
你打电话后
public static RingBuffer recreateRingBuffer(int n) {
Log.e(Constants.GLOBALTAG,"Recreating RingBuffer of Size "+n);
instance=null;
instance=new RingBuffer(n);
return instance;
}
你确实有两个对象。您只是为旧对象设置对 null 的引用并创建一个新对象。然后设置旧引用到这个新对象。但是旧对象的引用仍在您的代码中的某处使用。除非所有引用都为空,否则它不会被 GC。
当您提供重新创建的条件时,您正在破坏单身人士的真正目的。最好提供一个 setter 来更改您想要更改的任何参数,而不仅仅是重新创建它。
您没有为 mainactivity
或 guimanager
添加代码,所以这是任何人的猜测。
但是,如果对 RingBuffer
的引用未 "automatically" 更新,可能是因为您将引用存储在变量中,例如:
RingBuffer rb = RingBuffer.getInstance();
然后使用rb
变量。
如果您要更改 reference 对象,请不要这样做(您基本上是在堆上创建一个新地址的新对象,所有现有引用仍将保留旧地址)。实例,始终使用 getInstance
引用它。意思是,而不是做
rb.foo();
总是这样做:
RingBuffer.getInstance().foo();
这样,无论何时您引用 RingBuffer
的实例,您将引用真正的单例对象,并且永远不会引用您可能创建和丢弃的任何旧实例。
我以为我写对了,但我没有找到错误的地方。 我创建了一个单身人士 class(使用 apache commons 的环形缓冲区);这在 mainactivity 和 guimanager 中使用(都是我的实现) - 因此 ringbuffer 的单例 class。以上 classes 通过调用
获取单例的引用 RingBuffer.getInstance()
在某些时候,用户想要更改环形缓冲区的大小,因此我通过调用
重新创建单例 class RingBuffer.recreateRingBuffer()
问题:在重新创建单例实例后 class,我希望 mainactivity 和 guimanager 中的现有引用将自动修改为新引用(不同大小的 ringbuffer)。但是不,我仍然有旧的参考(旧尺寸的缓冲区)。换句话说,如何在修改引用时自动修改 getInstance() 的 return 值(因此调用方方法和 ringbuffer 在对象的同一副本上工作)
这是我的单身人士class
import java.util.Arrays;
import org.apache.commons.collections.buffer.CircularFifoBuffer;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.math3.stat.StatUtils;
import android.util.Log;
public class RingBuffer {
private CircularFifoBuffer buffer;
private int size;
private volatile static /*final*/ RingBuffer instance = new RingBuffer(7);
private RingBuffer(int n) {
size = n;
buffer = new CircularFifoBuffer(size);
}
public static RingBuffer getInstance() {
return instance;
}
public static RingBuffer recreateRingBuffer(int n) {
Log.e(Constants.GLOBALTAG,"Recreating RingBuffer of Size "+n);
instance=null;
instance=new RingBuffer(n);
return instance;
}
}
你打电话后
public static RingBuffer recreateRingBuffer(int n) {
Log.e(Constants.GLOBALTAG,"Recreating RingBuffer of Size "+n);
instance=null;
instance=new RingBuffer(n);
return instance;
}
你确实有两个对象。您只是为旧对象设置对 null 的引用并创建一个新对象。然后设置旧引用到这个新对象。但是旧对象的引用仍在您的代码中的某处使用。除非所有引用都为空,否则它不会被 GC。
当您提供重新创建的条件时,您正在破坏单身人士的真正目的。最好提供一个 setter 来更改您想要更改的任何参数,而不仅仅是重新创建它。
您没有为 mainactivity
或 guimanager
添加代码,所以这是任何人的猜测。
但是,如果对 RingBuffer
的引用未 "automatically" 更新,可能是因为您将引用存储在变量中,例如:
RingBuffer rb = RingBuffer.getInstance();
然后使用rb
变量。
如果您要更改 reference 对象,请不要这样做(您基本上是在堆上创建一个新地址的新对象,所有现有引用仍将保留旧地址)。实例,始终使用 getInstance
引用它。意思是,而不是做
rb.foo();
总是这样做:
RingBuffer.getInstance().foo();
这样,无论何时您引用 RingBuffer
的实例,您将引用真正的单例对象,并且永远不会引用您可能创建和丢弃的任何旧实例。