对于多线程的问题,你可以把synchronized加上!
public synchronized static SingleTon newInstance()另外你说返回null,那是你没有设计好!
你可以先在定义一个对象自身的实例SingleTon,当外部要求生成实例时,你先判断该实例变量SingleTon是否为空,如果不为空,刚简单返回该变量就是了,如果为空,刚生成该对象一个实例返回;
最后还要在finalize() 方法中加一句 singleTon=null,即让它为空值,
另外对于你想要N个实例的话,处理是一样的,而且你还可以设计得更灵活一点,比如就你先生成n个实例,好比一个实例池!平时就从该池中返回对象,而不用时又
让它收回就是了!

解决方案 »

  1.   

    1. yes. static init would not work. but, why do you need to do that?
    2. return null/proxy/throw exception/wait. just depend on what you want.
    3. finalize is not guaranteed to run even when the object can be gc'd. so, if gc never cellects the singletons, you're in trouble.
    one solution would be to use pool and to force the client code to call release()
    4. synchronized lah!
      

  2.   

    我也想知道如何实现object pool来解决问题呢能否给个小程序看看
      

  3.   

    a good object pool may use WeakReference or SoftReference to allow the pooled objects to be collected.but, object pool needs more coding than N-gleton.
    Here's the N-gleton code (don't have a pool, just an instance count):interface Resource{
        public void release();
        public void use();
    }
    interface ResourceCreator{
    public Resource create();
    }
    interface ResourceNgleton{
    public Resource getResource(ResourceCreator rc);
    public void release(Resource res);
    }
    class FailNullNgleton implements ResourceNgleton{
    private final int count;
    private final int max;
    private FailNullNgleton(int size){
    count = 0;
    max = size;
    }
    public Resource getResource(ResourceCreator rc){
    if(count >= max){
    return null;
    }
    else{
    count ++;
    return rc.create();
    }
    }
    public void release(Resource res){
    count--;
    }
    }class MyResource implements Resource{
    private final ResourceNgleton man;
        public void release(){man.release(this);}
        public void use(){System.out.println("use my resource");}
        private static final ResourceNgleton ngleton = new FailNullNgleton(20);
        public static Resource instance(){
         return ngleton.getResource(new ResourceCreator(){
         public Resource create(){return new MyResource(ngleton);}
         });
        }
        private MyResource(ResourceNgleton man){this.man = man;}
    }
    //client code like
    public class TestResource
    {
    public static void main(String[] args)
    {
    Resource res = null
    try{
    res = MyResource.instance();
    //......
    }
    finally{
    if(res != null) res.release();
    }

    }

    }//the FailNullNgleton will return null when reaching upper limit.
    //other alternative ngletons are as following:class FailExceptionNgleton implements ResourceNgleton{
    private final int count;
    private final int max;
    private FailExceptionNgleton(int size){
    count = 0;
    max = size;
    }
    public Resource getResource(ResourceCreator rc){
    if(count >= max)
    {
    throw new MaxInstanceNumberException(max);
    }
    else
    {
    count ++;
    return rc.create();
    }
    }
    public void release(Resource res){
    count--;
    }
    }class FailWaitNgleton implements ResourceNgleton{
    private final int count;
    private final int max;
    private FailWaitNgleton(int size){
    count = 0;
    max = size;
    }
    public synchronized Resource getResource(ResourceCreator rc){
    while(count >= max){
    wait();
    }
    count ++;
    return rc.create(); }
    public synchronized void release(Resource res){
    count--;
    notify();
    }
    }interface ResourceSemaphore{
    public boolean green();
    }
    class ResourceProxy implements Resource{
    private Resource res = null;
    private final ResourceCreator creator;
    private final ResourceSemaphore sem;
    public ResourceProxy(ResourceCreator cr, ResourceSemaphore sem)
    {
    this.creator = cr;
    this.sem = sem;
    }

    public void release()
    {
    if(res != null){
    res.release();
    }
    }
    public void use()
    {//defer the construction of the real resource object when actually used.
    if(res == null)
    {
    synchronized(sem){
    while(!sem.green()){
    sem.wait();
    }
    res = creator.create();
    }
    }
    res.use();

    }
    }
    class FailProxyNgleton implements ResourceNgleton, ResourceSemaphore{
    private final int count;
    private final int max;
    private FailProxyNgleton(int size){
    count = 0;
    max = size;
    }
    public boolean green(){return count<max;}
    public synchronized Resource getResource(ResourceCreator rc){
    if(count >= max)
    {
    return new ResourceProxy(rc, this);
    }
    else
    {
    count ++;
    return rc.create();
    }
    }
    public synchronized void release(Resource res){
    count--;
    notify();
    }
    }
      

  4.   

    Oops, FailProxyNgleton should be:
    interface ResourceSemaphore{
    public boolean green();
    public void inc();
    }
    class ResourceProxy implements Resource{
    private Resource res = null;
    private final ResourceCreator creator;
    private final ResourceSemaphore sem;
    public ResourceProxy(ResourceCreator cr, ResourceSemaphore sem)
    {
    this.creator = cr;
    this.sem = sem;
    }

    public void release()
    {
    if(res != null){
    res.release();
    }
    }
    public void use()
    {//defer the construction of the real resource object when actually used.
    if(res == null)
    {
    synchronized(sem){
    while(!sem.green()){
    sem.wait();
    }
    sem.inc();
    res = creator.create();
    }
    }
    res.use();

    }
    }
    class FailProxyNgleton implements ResourceNgleton, ResourceSemaphore{
    private final int count;
    private final int max;
    private FailProxyNgleton(int size){
    count = 0;
    max = size;
    }
    public boolean green(){return count<max;}
    public void inc(){count++;}

    public synchronized Resource getResource(ResourceCreator rc){
    if(count >= max)
    {
    return new ResourceProxy(rc, this);
    }
    else
    {
    count ++;
    return rc.create();
    }
    }
    public synchronized void release(Resource res){
    count--;
    notify();
    }
    }
      

  5.   

    here is an article on object pool from javaworld
    Build your own ObjectPool in Java to boost app speed 
    http://www.javaworld.com/javaworld/jw-06-1998/jw-06-object-pool.html