因此,我正在考虑建立一个业余爱好项目,一种类似的东西,只是为了了解我的编程/设计.
它基本上是一个多线程的Web蜘蛛,更新相同的数据结构对象 - > int.
因此,为此使用数据库绝对有点过分,我唯一能想到的是用于包含我的数据结构的线程安全单例.http://web.archive.org/web/20121106190537/http://www.ibm.com/developerworks/java/library/j-dcl/index.html
我应该注意一个不同的方法吗?
双重检查锁定已被证明是不正确和有缺陷的(至少在Java中).出于确切原因,请搜索或查看维基百科的条目.
首先是程序的正确性.如果您的代码不是线程安全的(在多线程环境中),那么它就会被破坏.在性能优化之前,首先是正确性.
要正确,你必须同步整个getInstance
方法
public static synchronized Singleton getInstance() { if (instance==null) ... }
或静态初始化它
private static final Singleton INSTANCE = new Singleton();
在Web爬网程序中对数据库使用延迟初始化可能不值得.延迟初始化增加了复杂性和持续的速度命中.一个合理的案例是,很有可能永远不需要数据.此外,在交互式应用程序中,它可用于减少启动时间并提供速度幻觉.
对于像web-crawler这样的非交互式应用程序,它肯定需要立即存在其数据库,懒惰初始化是不合适的.
另一方面,Web爬虫很容易并行化,并且可以从多线程中受益匪浅.使用它作为掌握java.util.concurrent
图书馆的练习将是非常值得的.具体来说,查看ConcurrentHashMap
和ConcurrentSkipListMap
,这将允许多个线程读取和更新共享映射.
当您摆脱延迟初始化时,最简单的Singleton模式是这样的:
class Singleton { static final Singleton INSTANCE = new Singleton(); private Singleton() { } ... }
关键字final
是关键所在.即使您为static
单例提供"getter"而不是允许直接字段访问,使单例final
有助于确保正确性并允许JIT编译器进行更积极的优化.