如何在Groovy中构建可重新初始化的惰性属性?

如何在Groovy中构建可重新初始化的惰性属性?,第1张

概述这就是我想做的事情: class MyObject { @Lazy volatile String test = { //initalize with network access }()}def my = new MyObject()println my.test//Should clear the property but throws groov 这就是我想做的事情:

class MyObject {    @Lazy volatile String test =  {        //initalize with network access    }()}def my = new MyObject()println my.test//Should clear the property but throws groovy.lang.ReadonlyPropertyExceptionmy.test = null //Should invoke a new initializationprintln my.test

不幸的是,惰性字段是Groovy中的只读字段,清除属性会导致异常.

知道如何重新实现惰性字段,而无需重新实现@Lazy注释提供的双重检查逻辑吗?

更新:

考虑soft = true(从第一个答案开始)让我进行了一些测试:

class MyObject {    @Lazy() volatile String test =  {        //initalize with network access        println 'init'        Thread.sleep(1000)        'test'    }()}def my = new MyObject()//my.test = null 10.times { zahl ->    Thread.start {println "$zahl: $my.test"}}

大约1秒后,我的Groovy控制台上会有以下输出:

init0: test7: test6: test1: test8: test4: test9: test3: test5: test2: test

这是预期的(和想要的).现在我添加soft = true,结果发生了显着变化,需要10秒钟:

initinit0: testinit9: testinit8: testinit7: testinit6: testinit5: testinit4: testinit3: testinit2: test1: test

也许我正在测试错误或soft = true完全破坏了缓存效果.有任何想法吗?

解决方法 你不能使用软 attribute of Lazy,即:

class MyObject {  @Lazy( soft=true ) volatile String test =  {    //initalize with network access  }()}

编辑

使用soft = true,注释会生成一个setter和一个getter,如下所示:

private volatile java.lang.ref.softReference $test public java.lang.String gettest() {    java.lang.String res = $test?.get()    if ( res != null) {        return res     } else {        synchronized ( this ) {            if ( res != null) {                return res             } else {                res = {                 }.call()                $test = new java.lang.ref.softReference( res )                return res             }        }    }}public voID setTest(java.lang.String value) {    if ( value != null) {        $test = new java.lang.ref.softReference( value )    } else {        $test = null    }}

如果没有soft = true,你就不会得到一个setter

private volatile java.lang.String $test public java.lang.String gettest() {    java.lang.Object $test_local = $test     if ( $test_local != null) {        return $test_local     } else {        synchronized ( this ) {            if ( $test != null) {                return $test             } else {                return $test = {                 }.call()            }        }    }}

所以变量是只读的.目前还不确定这是故意还是使用soft = true的副作用虽然…

编辑#2

这看起来可能是使用soft = true实现Lazy的一个错误

如果我们将getter更改为:

public java.lang.String gettest() {    java.lang.String res = $test?.get()    if( res != null ) {      return res     } else {      synchronized( this ) {        // Get the reference again rather than just check the existing res        res = $test?.get()        if( res != null ) {          return res        } else {          res = {             println 'init'            Thread.sleep(1000)            'test'          }.call()          $test = new java.lang.ref.softReference<String>( res )          return res         }      }    }  }

我认为它正在运作……我将开发一个修正错误

总结

以上是内存溢出为你收集整理的如何在Groovy中构建可重新初始化的惰性属性?全部内容,希望文章能够帮你解决如何在Groovy中构建可重新初始化的惰性属性?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1220553.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存