该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-17
呵呵 ajoo 别认真 , norther 也是想表达自己的想法, static 的确有不好的地方, 但是线程安全问题确是不存在的
|
|
返回顶楼 | |
发表时间:2008-05-17
Feiing 写道 呵呵 ajoo 别认真 , norther 也是想表达自己的想法, static 的确有不好的地方, 但是线程安全问题确是不存在的
这个存在不存在是要依赖上下文地。如果那个set仅仅是在系统初始化时候调用,以后都不再碰它(你怎么保证这一点?把它变成private么?还是放一个大写的DO NOT CALL ME!注释在那里?),而且初始化之后有一个同步动作,而且初始化过程中不会把那个static引用泄漏到别的线程,那么,确实,它是安全的。 不过即使如此,测试里面也不是安全的。假设一个测试setUp()里面调用了set,然后测试过程中某个地方启动了线程,那么这个线程能否看到正确地static引用都是不确定的。 |
|
返回顶楼 | |
发表时间:2008-05-17
的确 在容器中要保证线程安全以及引用不被改变只能靠人为约定
在 test case 里 setup() 设置了, 别的线程不一定能看到正确的 static 引用是为啥 我还真不知道 莫非是你以前说过的 junit 的问题 ? 那个帖子我没有认真看 |
|
返回顶楼 | |
发表时间:2008-05-17
ajoo 写道 Feiing 写道 呵呵 ajoo 别认真 , norther 也是想表达自己的想法, static 的确有不好的地方, 但是线程安全问题确是不存在的
这个存在不存在是要依赖上下文地。如果那个set仅仅是在系统初始化时候调用,以后都不再碰它(你怎么保证这一点?把它变成private么?还是放一个大写的DO NOT CALL ME!注释在那里?),而且初始化之后有一个同步动作,而且初始化过程中不会把那个static引用泄漏到别的线程,那么,确实,它是安全的。 不过即使如此,测试里面也不是安全的。假设一个测试setUp()里面调用了set,然后测试过程中某个地方启动了线程,那么这个线程能否看到正确地static引用都是不确定的。 呵呵,代码级别是没有办法控制,但是应用一个机制之前应该对它有一定了解,就像写servlet没人会把每次request的状态保存在instance里一样,是需要知道servlet是单例的,这个servlet也控制不了的。 测试只能小心点去给他set null,这确实不爽,或者写个扩展一下TestCase,每个test都用不同的classloader。 |
|
返回顶楼 | |
发表时间:2008-05-17
Feiing 写道 的确 在容器中要保证线程安全以及引用不被改变只能靠人为约定
在 test case 里 setup() 设置了, 别的线程不一定能看到正确的 static 引用是为啥 我还真不知道 莫非是你以前说过的 junit 的问题 ? 那个帖子我没有认真看 跟junit没关系。java的变量,只有volatile的和final的才保证线程间的可见性。 |
|
返回顶楼 | |
发表时间:2008-05-17
Norther 写道 ajoo 写道 Feiing 写道 呵呵 ajoo 别认真 , norther 也是想表达自己的想法, static 的确有不好的地方, 但是线程安全问题确是不存在的
这个存在不存在是要依赖上下文地。如果那个set仅仅是在系统初始化时候调用,以后都不再碰它(你怎么保证这一点?把它变成private么?还是放一个大写的DO NOT CALL ME!注释在那里?),而且初始化之后有一个同步动作,而且初始化过程中不会把那个static引用泄漏到别的线程,那么,确实,它是安全的。 不过即使如此,测试里面也不是安全的。假设一个测试setUp()里面调用了set,然后测试过程中某个地方启动了线程,那么这个线程能否看到正确地static引用都是不确定的。 呵呵,代码级别是没有办法控制,但是应用一个机制之前应该对它有一定了解,就像写servlet没人会把每次request的状态保存在instance里一样,是需要知道servlet是单例的,这个servlet也控制不了的。 测试只能小心点去给他set null,这确实不爽,或者写个扩展一下TestCase,每个test都用不同的classloader。 很多人对ww的request scope action有意见,我反而认为servlet规范的单例设计的不好。ww走的才是正确的革命路线。 |
|
返回顶楼 | |
发表时间:2008-05-17
ajoo 写道 Norther 写道 ajoo 写道 Feiing 写道 呵呵 ajoo 别认真 , norther 也是想表达自己的想法, static 的确有不好的地方, 但是线程安全问题确是不存在的
这个存在不存在是要依赖上下文地。如果那个set仅仅是在系统初始化时候调用,以后都不再碰它(你怎么保证这一点?把它变成private么?还是放一个大写的DO NOT CALL ME!注释在那里?),而且初始化之后有一个同步动作,而且初始化过程中不会把那个static引用泄漏到别的线程,那么,确实,它是安全的。 不过即使如此,测试里面也不是安全的。假设一个测试setUp()里面调用了set,然后测试过程中某个地方启动了线程,那么这个线程能否看到正确地static引用都是不确定的。 呵呵,代码级别是没有办法控制,但是应用一个机制之前应该对它有一定了解,就像写servlet没人会把每次request的状态保存在instance里一样,是需要知道servlet是单例的,这个servlet也控制不了的。 测试只能小心点去给他set null,这确实不爽,或者写个扩展一下TestCase,每个test都用不同的classloader。 很多人对ww的request scope action有意见,我反而认为servlet规范的单例设计的不好。ww走的才是正确的革命路线。 完蛋了,这次观点一致了,我也认为WW的那样更合适,重新举个例子,但是应用一个机制之前应该对它有一定了解,就像用Hibernate的Lazy load,你的entity必须不能是final的,final不final,Hibernate也保证不了?: p |
|
返回顶楼 | |
发表时间:2008-05-17
ajoo 写道 Feiing 写道 的确 在容器中要保证线程安全以及引用不被改变只能靠人为约定
在 test case 里 setup() 设置了, 别的线程不一定能看到正确的 static 引用是为啥 我还真不知道 莫非是你以前说过的 junit 的问题 ? 那个帖子我没有认真看 跟junit没关系。java的变量,只有volatile的和final的才保证线程间的可见性。 有相应的 spec 吗 ? 照我以前的理解 volatile 是为了保证并发写操作的线程安全, 而 final 是为了防止引用被改变, 如果一个 static 变量保证只被初始化一次, 也会有可见性问题吗 ? |
|
返回顶楼 | |
发表时间:2008-05-17
比较讨厌Spring的注释满街跑。
一直是这么干的... public aspect FinderInitialization { private pointcut getXXXFinder() : get(public static * IDomainObject+.*Finder); Object around() : getXXXFinder(){ Object finder = proceed(); if(finder == null) { //注入 ... finder = proceed(); } assert finder != null : thisJoinPoint.getSignature().toShortString() + " 返回 null "; return finder; } } 我们通常不会把Finder注入到需要它的DomainObject中,那样不太经济,相反,我们仅仅把Finder注入,它所返回的DomainObject中。一个Finder仅仅只在一个地方被注入。 静态编译AspectJ,之慢当然不能忍受,实际动态织入还是曼快的,后面发布的jrockit性能又有提升。 |
|
返回顶楼 | |
发表时间:2008-05-17
partech 算是忠实的 aspectj fans 了
|
|
返回顶楼 | |