- 浏览: 3015926 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
看老赵几天前提到double-check,昨天又提到属性的lazy加载,想起记这么一点:
在实现单例的时候,你是否真的需要用double-check之类的技巧来实现lazy创建实例?
使用单例模式但又想让它lazy创建实例,理由通常是“实例的创建可能伴随一些复杂的初始化计算,或者需要持有一些外部资源之类;如果程序中并没有使用到那个实例,那么付出的代码就白费了”。
但很多时候上述理由是个伪命题:不使用的类根本就不会被初始化。既然没有初始化,就不会付出代价去创建单例的实例。
Effective Java, 2nd推荐在Java 5或更新的版本中使用enum来实现Singleton模式。那看看这段代码的输出:
结果是:
虽然定义了Singleton类型,但程序中并没有使用它,所以也就没有引发它的初始化。
那么在main()里添加一行:
结果变为:
哪儿用哪儿才初始化。
只要实现Singleton的时候,该类上没有别的对外公开的静态变量或者静态方法,外界想要使用Singleton实例只能通过INSTANCE的话,那引发Singleton初始化的只有对INSTANCE的访问(这时初始化是正确的)或者通过反射(例如Class.forName(),这是例外情况)。
要是有信心代码里不会出现“例外情况”的话,又何必费神去实现double-check呢?
C#里则有些细微差异。某个类的静态初始化“想当然”也应该是初次使用的时候才进行,但实际上这取决于静态初始化逻辑是怎么写的。如果写成:
虽然代码中有Foo()使用了Singleton,但实际执行路径上没有经过Foo(),其它地方也没用过Singleton类,于是输出结果是:
但要是在Main()里添加一行:
输出结果跟想像的可能就不一样了:
这是因为C#中直接在静态变量声明的地方就初始化,而且没有显式提供静态构造器实现的话,会使类带上beforefieldinit标记,使得类的静态初始化提早执行。稍微改改,给Singleton类添加一个空的静态构造器的话……
会发现执行结果变为:
这种写法就不会使类带上beforefieldinit,于是初始化时间就跟“想像中”的一样,哪儿用到哪儿才初始化。把Instance的初始化整个挪到静态构造器里的结果也一样。
有时候费了力气去写个double-check搞不好还写错了,要是回头发现其实不用自己费神写lazy逻辑也能达到效果的话,那肯定郁闷坏了。引用老赵的帖的标题:如果是能简单解决的问题,就不用想得太复杂了
^ ^
嗯我知道这个办法。C#里应该也可以用吧,原理差不多。不过我没测试过,回头试试。
Guice 这边还有一种 singleton . 不过不知道在c#上是不是也适用..
在实现单例的时候,你是否真的需要用double-check之类的技巧来实现lazy创建实例?
使用单例模式但又想让它lazy创建实例,理由通常是“实例的创建可能伴随一些复杂的初始化计算,或者需要持有一些外部资源之类;如果程序中并没有使用到那个实例,那么付出的代码就白费了”。
但很多时候上述理由是个伪命题:不使用的类根本就不会被初始化。既然没有初始化,就不会付出代价去创建单例的实例。
Effective Java, 2nd推荐在Java 5或更新的版本中使用enum来实现Singleton模式。那看看这段代码的输出:
public class Program { public static void main(String[] args) { System.out.println("main()"); System.out.println("leaving main()"); } } enum Singleton { INSTANCE; Singleton() { System.out.println("Singleton()"); } }
结果是:
引用
main()
leaving main()
leaving main()
虽然定义了Singleton类型,但程序中并没有使用它,所以也就没有引发它的初始化。
那么在main()里添加一行:
public class Program { public static void main(String[] args) { System.out.println("main()"); Singleton s = Singleton.INSTANCE; System.out.println("leaving main()"); } } enum Singleton { INSTANCE; Singleton() { System.out.println("Singleton()"); } }
结果变为:
引用
main()
Singleton()
leaving main()
Singleton()
leaving main()
哪儿用哪儿才初始化。
只要实现Singleton的时候,该类上没有别的对外公开的静态变量或者静态方法,外界想要使用Singleton实例只能通过INSTANCE的话,那引发Singleton初始化的只有对INSTANCE的访问(这时初始化是正确的)或者通过反射(例如Class.forName(),这是例外情况)。
要是有信心代码里不会出现“例外情况”的话,又何必费神去实现double-check呢?
C#里则有些细微差异。某个类的静态初始化“想当然”也应该是初次使用的时候才进行,但实际上这取决于静态初始化逻辑是怎么写的。如果写成:
using System; public class Singleton { public static Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton()"); } } static class Program { static void Main(string[] args) { Console.WriteLine("Main()"); Console.WriteLine("leaving Main()"); } static void Foo() { var s = Singleton.Instance; } }
虽然代码中有Foo()使用了Singleton,但实际执行路径上没有经过Foo(),其它地方也没用过Singleton类,于是输出结果是:
引用
Main()
leaving Main()
leaving Main()
但要是在Main()里添加一行:
using System; public class Singleton { public static Singleton Instance = new Singleton(); private Singleton() { Console.WriteLine("Singleton()"); } } static class Program { static void Main(string[] args) { Console.WriteLine("Main()"); var s = Singleton.Instance; Console.WriteLine("leaving Main()"); } static void Foo() { var s = Singleton.Instance; } }
输出结果跟想像的可能就不一样了:
引用
Singleton()
Main()
leaving Main()
Main()
leaving Main()
这是因为C#中直接在静态变量声明的地方就初始化,而且没有显式提供静态构造器实现的话,会使类带上beforefieldinit标记,使得类的静态初始化提早执行。稍微改改,给Singleton类添加一个空的静态构造器的话……
using System; public class Singleton { public static Singleton Instance = new Singleton(); static Singleton() { } private Singleton() { Console.WriteLine("Singleton()"); } } static class Program { static void Main(string[] args) { Console.WriteLine("Main()"); var s = Singleton.Instance; Console.WriteLine("leaving Main()"); } static void Foo() { var s = Singleton.Instance; } }
会发现执行结果变为:
引用
Main()
Singleton()
leaving Main()
Singleton()
leaving Main()
这种写法就不会使类带上beforefieldinit,于是初始化时间就跟“想像中”的一样,哪儿用到哪儿才初始化。把Instance的初始化整个挪到静态构造器里的结果也一样。
有时候费了力气去写个double-check搞不好还写错了,要是回头发现其实不用自己费神写lazy逻辑也能达到效果的话,那肯定郁闷坏了。引用老赵的帖的标题:如果是能简单解决的问题,就不用想得太复杂了
^ ^
评论
4 楼
mercyblitz
2010-06-23
这是ClassLoader机制加载的,记载类的时候就synchronized啦,因此不会出现重复加载或者不可见的情况。
3 楼
RednaxelaFX
2009-09-06
Saito 写道
嗯我知道这个办法。C#里应该也可以用吧,原理差不多。不过我没测试过,回头试试。
2 楼
Saito
2009-09-06
睡糊涂了.. url 点成 quote 了..
1 楼
Saito
2009-09-06
引用
http://crazybob.org/2007/01/lazy-loading-singletons.html
Guice 这边还有一种 singleton . 不过不知道在c#上是不是也适用..
发表评论
-
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
基于LLVM实现VM的JIT的一些痛点
2014-01-07 17:25 0同事Philip Reames Sanjoy Das http ... -
tailcall notes
2013-12-27 07:42 0http://blogs.msdn.com/b/clrcode ... -
《自制编程语言》的一些笔记
2013-11-24 00:20 0http://kmaebashi.com/programmer ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22253(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21370(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
Function.prototype.bind
2013-09-24 18:07 0polyfill http://stackoverflow. ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ... -
struct做参数不能从寄存器传?
2013-08-28 23:33 0test test test struct Foo { i ... -
也谈类型: 数据, 类型, 标签
2013-08-18 01:59 0numeric tower http://en.wikiped ... -
SDCC 2012上做的JVM分享
2012-10-17 16:35 32546刚把在SDCC 2012做的JVM分享的演示稿上传了。 演示 ... -
运行时支持系统的“重量”
2012-10-12 16:08 0运行时支持系统的“重量” 好久没写博客了,可写的话题已经堆积 ... -
class?metaclass?meta-what?
2011-04-05 19:43 0http://en.wikipedia.org/wiki/Me ... -
“代码模式”与抽象
2010-10-28 15:21 0嗯,我是说“代码模式”,不是“设计模式”;这里指的是在给定的场 ... -
lvalue与rvalue
2010-09-03 00:40 0http://en.wikipedia.org/wiki/Va ... -
动态链接的“依据”
2010-02-09 09:54 0动态链接,意味着在生成的“东西”里留有符号信息,等到运行时再r ...
相关推荐
System.Lazy<T> 实例的延迟初始化值
使用此宏,可能具有static ,这些static要求在运行时执行代码才能进行初始化。 这包括需要堆分配的任何内容,例如向量或哈希图,以及需要计算非const函数调用的所有内容。最小支持的rustc 1.27.2+ 此版本已在CI中...
lazy-static.rs, 在 Rust 中,用于定义惰性计算的static 变量的小宏 lazy-static.rs在 Rust 中声明延迟求值的静态的宏。使用这里宏,可以以使 static s 在运行时要求执行代码,以便初始化。 这包括需要堆分配,如...
向对象添加延迟初始化的属性。 例子 var addLazyProperty = require ( "lazy-property" ) var obj = { } addLazyProperty ( obj , "foo" , function ( ) { console . log ( "initialized!" ) return "bar" } ) //...
Lazy
java stream的初始化及懒加载源代码, 文章《java 中Stream初始化及懒调用(Lazy Invocation)》 地址:https://blog.csdn.net/2301_77345366/article/details/130017616
在Swift 5.1中具有延迟初始化值的几种方法。 请注意,如果您对Swift的lazy关键字的行为感到满意,则应使用该关键字。 这是针对: :不可重置的惰性模式,以确保Swift语言版本之间的惰性行为 :可惰性模式,其值仅在...
Lazyload是通过延迟加载来实现按需加载,达到节省资源,加快浏览速度的目的。 网上也有不少类似的效果,这个Lazyload主要特点是: 支持使用window(窗口)或元素作为容器对象; 对静态(位置大小不变)元素做了大量...
在许多情况下,必须对私有/受保护的属性进行延迟初始化,许多人编写的类如下所示: class SomeService { protected $ dependency ; public function doWork () { $ this -> getDependency ()-> delegateWork ()...
2-创建一个静态私有变量数据类型是当前类的数据类型且不进行初始化 3-提供一个公有静态的获取当前对象的方法 4-进行判断, 若当前对象没有被创建, 创建对象, 否则返回 object LazyDemo extends App { def init():...
jQuery_lazyload插件示例Demo
Lazy_Theta_star是在 Theta_star上的进一步改进,Theta_star是当节点加入open表时和当前点的父节点进行比较g值是否更小,对一些不必要的节点计算浪费了时间,而Lazy_Theta_star则是在弹出open表后进行比较,减少了...
lazyload, JavaScript, 图片懒加载, h5
图片懒加载lazyload,增快页面访问速度。
Lazy Load Plugin for jQuery
博客与文章作为例子,查询一个博客的时候并不是需要将其下面的文章都加载进来。把需要延迟加载的属性使用Lazy泛型,实例时候传入一个Fun委托。
Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预加载的处理方式正好是相反的. 在包含很多...
lazyload技术内幕,当下最流行的图片浏览技术
LazyObject.js 允许您定义对象的属性,该对象的值仅在第一次访问时初始化。 从那时起,值被缓存/记忆。 它的defineLazyProperty函数紧跟Object.defineProperty签名,允许您更改定义的属性是否可configurable 、 ...
Lazy Nezumi Pro 是一个 Windows 应用程序,可以帮助你画出流畅,优美的线条,用鼠标或手写板。 它能与许多你喜爱的程序协作。可以让你拥有独特的笔刷稳定系统。本工具支持绝大多数的 2D 和 3D 绘图软件。 在 ...