【问题标题】:Thread-safe Singleton class线程安全的单例类
【发布时间】:2022-02-04 16:21:54
【问题描述】:

在我的项目中,我正在尝试使用单例类在其中存储数据。当我试图从 Service 类访问它时,它会创建新实例而不是使用以前的 Singleton 实例。我在 github 上阅读了很多帖子,但找不到有效的答案

我的单身课程

import android.util.Log;
import com.softelnet.ksavi.android.model.AttachmentRequest;
import java.util.LinkedList;

public class AttachmentsUpdateQueue {


    private static class Holder {
        private static final AttachmentsUpdateQueue singleInstance = new AttachmentsUpdateQueue();
    }


    private AttachmentsUpdateQueue() {
        Log.d("pox", "new instance");
    }

    private LinkedList<AttachmentRequest> attachmentsQueue = new LinkedList<>();

    public static AttachmentsUpdateQueue getInstance() {
        return Holder.singleInstance;

    }

    public AttachmentRequest getAttachmentForUpload() {
        Log.d("pox", "get, size:" + attachmentsQueue.size());
        if (attachmentsQueue.size() > 0) {
            return attachmentsQueue.get(0);
        } else {
            return null;
        }

    }

    public int getSize() {
        return attachmentsQueue.size();
    }

    public void addAttachmentForUpload(AttachmentRequest attachment) {
        attachmentsQueue.addLast(attachment);
        Log.d("pox", "added, size:" + attachmentsQueue.size());
    }
}

向单例添加数据

AttachmentsUpdateQueue.getInstance().addAttachmentForUpload(new AttachmentRequest(oprCtx.getUser(),task.getId(),attachment,isAttribute));

从单例中获取数据

 AttachmentRequest req = AttachmentsUpdateQueue.getInstance().getAttachmentForUpload();

【问题讨论】:

  • 它在哪里创建一个新实例?
  • 创建单例的最佳方法是使用 Java 枚举。快速阅读:baeldung.com/java-singleton
  • 当我尝试访问服务类中的单例时。第一次尝试以创建一个新实例结束
  • 你为什么要为 Singleton 询问一些“持有人”类而不是询问 Singleton 本身?
  • @hfontanez ,因为我试图以各种方式对其进行编码,希望我能找到一个可行的方法

标签: java android multithreading service singleton


【解决方案1】:

也许你可以这样写,命名为DCL(double check lock)。

private volatile static AttachmentsUpdateQueue instance = null;
private AttachmentsUpdateQueue(){
    System.out.println("Single: " + System.nanoTime());
}

public static AttachmentsUpdateQueue getInstance(){
    if(instance == null){
        synchronized (AttachmentsUpdateQueue.class) {
            if(instance == null){
                singleInstance = new AttachmentsUpdateQueue();
            }
        }
    }
    return instance;
}

【讨论】:

  • 只使用一个枚举......
  • 它不工作:/
  • D/pox: Single: 19904804726440 D/pox: przed 434745232D/pox: added, size:1 D/pox: Single: 19918035672210 D/pox: get, size:0 D/pox: its null D/pox: 上传附件
  • 这是不正确的。 OP 使用的单例持有者模式在各方面都优于此。
  • 为什么不工作?应该没问题,我也用在我的项目中。如果是这样,枚举也是一个好方法。公共枚举单例{实例; public void getInstance() { System.out.println("doSomething"); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多