java – 这种创建Singleton线程的方法是否安全?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 这种创建Singleton线程的方法是否安全?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4429字,纯文字阅读大概需要7分钟。
内容图文
![java – 这种创建Singleton线程的方法是否安全?](/upload/InfoBanner/zyjiaocheng/810/ffef0789538e46a490a03ab6b844abf3.jpg)
这不是关于Singleton是好还是坏的讨论.它是关于创建单身人士.我理解Singleton的方式是它是一个类,任何时候都应该存在一个对象的大多数.也就是说,如果几个类同时实例化一个单例,那么它们将共享该单例的单个实例.
单例的问题在于,一旦创建它,??它将在应用程序的持续时间内存在.使用我的方法,您可以创建并在任何时候收集Singleton垃圾,如果它不再使用的话.好吧,我需要一个枚举(Singleton!)来创建所有其他Singleton.我认为我的方法是反射和序列化安全,但我不确定线程??是否有任何问题.
我创建单例的方法如下:
首先,任何想要成为单身人士的类都必须扩展以下类
public abstract class Singleton {
public Singleton(SingletonFactory.SingletonParam singletonParam) {
if (singletonParam == null) {
throw new NullPointerException("singletonParam cannot be null)");
}
}
// For singleton to release resources.
public abstract void destroy(SingletonFactory.SingletonParam singletonParam);
}
SingletonParam将是一个抽象类内部类,它不能拥有一个对象,它是多态性意义上的SingletonParam,在其容器类之外实例化.
这不是为了让子类在运行时扩展Singleton类.它是通过拥有静态实例的单例类.我的方法不需要单例类的任何静态实例.
容器是以下类
注意:在阅读了Stephen C的答案后,我进行了更改以从构造函数初始化HashMap,我不明白为什么它不是线程安全的.
public enum SingletonFactory {
INSTANCE;
enum SingletonList {
A,
B,
......
}
private final HashMap<String, SingletonInfo> mfSingletonInfoHashMap = new HashMap<>();
// Added after @Stephen C answer
SingletonFactory() {
mfSingletonInfoHasmap.put(A, final new SingletonInfo());
// put all the members of the SingletonList here.
At this time the Singleton member of the SingletonInfo is null.
It will be instantiated when a class call getSingleton
}
private class SingletonInfo {
final Set callingObjects = new HashSet();
Singleton singleton;
}
public Object getSingleton(SingletonList inList, Object object) {
final SingletonInfo singletonInfo = mfSingletonInfoHashMap.get(inList);
synchronized (singletonInfo) {
if (singletonInfo.callingObjects.add(object)) {
if (singletonInfo.singleton == null) {
singletonInfo.singleton = createSingleton(singletonClassName);
}
} else {
throw new RuntimeException("getSingleton(" + singletonClassName + ") has already been called and not released");
}
return singletonInfo.singleton;
}
public void releaseSingleton(SingletonList inList, Object object) {
SingletonInfo singletonInfo = mfSingletonInfoHashMap.get(inList);
synchronized (singletonInfo) {
singletonInfo.callingObjects.remove(object);
if (singletonInfo.callingObjects.isEmpty()) {
singletonInfo.singleton.destroy(new SingletonParam() {
});
singletonInfo.singleton = null;
}
}
}
private Singleton createSingleton(SingletonList inList) {
switch(inList) {
case SingletonA:
return new SingletonA(new SingletonParam() {});
......
}
}
public abstract class SingletonParam {
private SingletonParam() {
}
}
}
以上是不对的,因为您必须扩展包含SingletonInfo中的CallingObjects的HashSet,以通过引用实现相等性,并且在默认实现中不相等.
由于SingletonParam的子类的实例无法在SingletonFactory之外实例化,因此创建单例对象的唯一方法是调用SingletonFactory.INSTANCE.getSingleton(you_singleton_class_name,this)
解决方法:
原始版本不是线程安全的. getSingleton方法在不同步任何内容的情况下读取和更新HashMap.
I see there maybe a problem when there is no SingletonInfo associates with a singleton class name yet.
正确.
这是关于代码的更新版本:
In that case I can just populate my hashmap with all the singleton class names with empty CallingObjecs and null Singleton and then synchronize on the SingletonInfo. Does that sound right?
是的,前提是:
>初始化发生在SingletonFactory构造函数中,
> hashmap安全发布,并且
>在构建工厂之后,没有任何更改hashmap.
但是,这似乎会破坏您最初实施的优势之一;即,单身工厂不是单身人士的先验知识.
更好的方法(即保留原始尝试解决方案的优点的方法)是同步访问HashMap,或使用ConcurrentHashMap …及其特殊的原子操作.
Since I learn programming just by coding and no formal training …
如果您要学习正确使用Java并发,至少需要阅读有关Java Concurrency的优秀教科书.试试Goetz等人.
(您需要了解Java并发的原则.您不太可能通过反复试验来学习它们.)
(IMO)关于你如此专注于使单身人士设计模式发挥作用,当“接受的智慧”是单身人士是一个坏主意.您是否考虑过依赖注入及其优势?
另一件事是这些不是真正的单身人士.
> Singleton类的隐含语义与其名称相矛盾. Singleton可以有多个实例……
>没有什么可以阻止某人创建给定Singleton子类的多个实例.根据您的实现方法,每个suclass需要有一个非私有构造函数,以便工厂工作.
>除非你将Singleton子类声明为final,否则这将提供另一条破坏单例的途径.
简而言之,我不相信你正在构建的这个基础设施将实现你更好地实现(真正的)单身人士的目标.
内容总结
以上是互联网集市为您收集整理的java – 这种创建Singleton线程的方法是否安全?全部内容,希望文章能够帮你解决java – 这种创建Singleton线程的方法是否安全?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。