我一直想知道懒惰评估为何有用.我还没有任何人以有道理的方式向我解释; 最重要的是它最终沸腾到"相信我".
注意:我不是指记忆.
从Head First设计模式书中,具有双重检查锁定的单例模式已实现如下:
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么volatile被使用.volatile使用不会 破坏使用双重检查锁定的目的,即性能?
java singleton design-patterns locking double-checked-locking
根据Android文档,它声明:
通常不需要子类Application.在大多数情况下,静态单例可以以更模块化的方式提供相同的功能.如果你的单例需要一个全局上下文(例如注册广播接收器),那么检索它的函数可以给出一个
Context.getApplicationContext()在首次构造单例时内部使用的Context .
我如何创建一个具有全局上下文的静态单例,以便它能够在我的应用程序中更改正在运行的活动?是否有足够的静态上下文引用getApplicationContext()?
我最近接受了一次采访,他向我询问了关于它们如何实现的Singleton Design Patterns,并告诉他使用静态变量和静态方法我们可以实现Singleton Design Patterns.
他似乎对答案感到满意,但我想知道
关于Singleton的任何意见都会受到高度赞赏,在处理Singletons时要记住哪些主要内容?
谢谢.
我有一个单身人士课程:
public class School {
private HashMap<String, String> students;
private static School school;
private School(){
students = new HashMap<String, String>();
}
public static School getInstance(){
if(school == null){
school = new School();
}
return school;
}
//Method to add student
protected void addStudent(String id, String name){
students.put(id,name);
}
//Method to remove student
protected void removeStudent(String id){
students.remove(id);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您在上面所看到的,在单例类中,我有一个students变量(a HashMap),有一些方法可以在类中添加和删除学生.
在我的应用程序,有可能是使用这个多线程School类getInstance(),然后添加和删除学生.为了使访问(特别是对 students 实例的访问)是线程安全的,我想在方法中使用synchorized关键字getInstanc(),如: …
在Effective Java第2章中,项目1 Bloch建议考虑使用静态工厂方法而不是构造函数来初始化对象.他提到的好处是这个模式允许类从重复的调用返回相同的对象:
静态工厂方法从重复调用返回同一对象的能力允许类在任何时候保持对存在的实例的严格控制.执行此操作的类称为实例控制.编写实例控制类有几个原因.实例控制允许类保证它是单例(第3项)或不可实例化(第4项).此外,它允许不可变类(第15项)保证不存在两个相等的实例:a.equals(b)当且仅当a == b时.
这种模式在多线程环境中如何工作?例如,我有一个应该由实例控制的不可变类,因为一次只能存在一个具有给定ID的实体:
public class Entity {
private final UUID entityId;
private static final Map<UUID, Entity> entities = new HashMap<UUID, Entity>();
private Entity(UUID entityId) {
this.entityId = entityId;
}
public static Entity newInstance(UUID entityId) {
Entity entity = entities.get(entityId);
if (entity == null) {
entity = new Entity(entityId);
entities.put(entityId, entity);
}
return entity;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我newInstance()从分离的线程调用会发生什么?如何让这个类线程安全?
我很困惑.我在java中发现了许多Singleton Design Pattern的实现.我发现的其中一个实现如下:
public class MySingleton {
private static class Loader {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return Loader.INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
如下所述:https://stackoverflow.com.现在,如果这个实现应该工作,为什么不以下?
public class MySingleton {
private static final MySingleton INSTANCE = new MySingleton();
private MySingleton () {}
public static MySingleton getInstance() {
return INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
我搜索了java如何处理初始化,但找不到任何显示后面的代码将无法正常工作.相反,我发现了以下内容:stackoverflow.com,它指出每个静态初始化都发生在调用类的静态方法之前,因此当访问INSTANCE(getInstance)的唯一方法是,则应该初始化持有单例实例的静态字段.调用.所以是的,我真的很困惑:如果这段代码有效,为什么不使用这个简单版本的单例设计模式呢?
我正在尝试使Clients类成为单例,但它不起作用。这是我的课:
public class Clients {
private static Clients instance = null;
private ArrayList<Client> cList;
private Clients() {
cList = new ArrayList<Client>();
}
public static Clients getInstance() {
if (instance == null) {
System .out.println("created");
instance = new Clients();
}
return instance;
}
public static ArrayList<Client> getcList() {
return getInstance().cList;
}
public static void setcList(ArrayList<Client> cList) {
getInstance().cList = cList;
}
}
Run Code Online (Sandbox Code Playgroud)
我在两个不同的类中得到这个实例(都有自己的主要功能)。在一个类中获取它的实例后,我在另一个类中获取它,但两个 tiare 仍在执行。
为什么 Java 的 switch 枚举在第一次运行时比它的“if”等价物慢得多?
我知道 JVM 需要“预热”才能可靠地测量性能。因此,每个第一次调用都比任何后续调用慢得多。这并不意味着我们无法根据每次首次运行来衡量性能。
测试标准是:
if语句或switch语句评估的传递值返回整数。我首先测试了枚举,预计性能会略有不同。
相反,我得到的平均值是:
77596纳秒 - 如果585232纳秒 - 开关我想看看是否只有枚举具有这种不利的属性,因此我还使用整数和字符串对其进行了测试(从 Java 7 开始,可以在 switch 语句中使用字符串)
INTS:
2308纳秒 - 如果1950纳秒 - 开关字符串:
8517纳秒 - 如果8322纳秒 - 开关这两个测试都产生非常相似的结果,表明 if 和 switch 语句在每次运行中都是等效的、非常相似或同样好,但是枚举的情况并非如此。
我在 Windows 和 Linux 上使用 Java 8 和 Java 17 进行了测试。
这是开关枚举代码:
public class SwitchEnum{
public static void main(String[] args){
long st = …Run Code Online (Sandbox Code Playgroud)