Asynchronous 如何在Kotlin中同步检查和设置变量?

Asynchronous 如何在Kotlin中同步检查和设置变量?,asynchronous,kotlin,Asynchronous,Kotlin,我有一个可变的null属性。我想签入一个方法,如果它的值为null,那么将它设置为一个新创建的对象。然后我将调用属性的方法(旧的或新的,但现有的对象) 这应该是线程安全的。在科特林我怎么能做到 使用.let,我无法重新分配属性。使用synchronized(…)或with lock时,在赋值和调用之间,线程可能会被另一个线程中断。或者至少IDE这么说,智能演员是不可能的。我不明白,如果没有同步块,为什么同步了 var starterTask: AsyncTask<MyData, Void,

我有一个可变的null属性。我想签入一个方法,如果它的值为null,那么将它设置为一个新创建的对象。然后我将调用属性的方法(旧的或新的,但现有的对象)

这应该是线程安全的。在科特林我怎么能做到

使用
.let
,我无法重新分配属性。使用
synchronized(…)
with lock
时,在赋值和调用之间,线程可能会被另一个线程中断。或者至少IDE这么说,智能演员是不可能的。我不明白,如果没有同步块,为什么
同步了

var starterTask: AsyncTask<MyData, Void, Void>? = null

fun start() {
    make it thread safe {
        if (starterTask == null) {
            starterTask = a child of AsyncTask()
        }
        starterTask.execute(this) // <- no !! operator
    }
}
var start任务:异步任务?=无效的
有趣的开始{
确保线程安全{
if(starterTask==null){
starterTask=AsyncTask()的子级
}
starterTask.execute(this)//您可以使用

val starterTask = lazy { a child of AsyncTask() }

fun start() {
    starterTask.execute(this)

默认的线程安全模式是
SYNCHRONIZED
,因此它符合您的需要。

如果您发布示例代码,它会更清晰。Smart cast inside
SYNCHRONIZED
块不起作用,因为尽管您知道这是修改变量的唯一地方,但编译器不知道这一点,并且仍然必须假设可能存在另一个setter会使你的
同步的
块失败。对不起,什么?这就是为什么同步:我们告诉编译器块必须不间断地执行。我们设置了锁,因此如果任何其他线程访问资源,它就会等待。如果我们什么也得不到,为什么我们要这样做,因为编译器会ldn不在乎?即使在同步块中访问变量,也不意味着不能从代码中其他不受保护的位置访问同一变量。例如,在“使其线程安全”之后-block one可以编写
starterTask=null
你能用一个惰性的
替换所有的代码,并让编译器为你做这一切吗?@gpto锁就是用来做这件事的。在受保护的块之前/之后有什么语句无关紧要。这可能会起作用,谢谢。(事实上,我发现我的应用程序中不需要这个部分。)然而,据我所知,lazy创建了一个“本地副本”我已经知道,如果我为我的数据制作一个局部变量副本,我就不需要对它进行空检查,因为局部变量不能被其他线程修改。但是你不需要在Java中这样做。还有其他方法吗?我不明白你有什么困扰。也许你最好问一个新问题。当然当然,正如委托所暗示的,还有第二个对象在起作用。如果您使用IntelliJ或类似的工具,只需导航到
惰性的实现(Ctrl+B),这可能会澄清一些问题。在这里,您将看到,一旦计算出实际值,就不需要进行同步。这是一个更为理论化的问题。测试和设置然后使用是同步、原子操作等最基本的部分,我只想知道它在另一种方式下是可能的。全局访问+锁定与本地复制模式不同。好的,我仔细查看了它。这不是我需要的,您完全更改了我的代码。
start()
将被大量调用,大约有一半的时间需要创建一个新对象。
starterTask
在我的代码片段中的角色不仅仅是
lateinit
的一个实现,lazy
peroperty将存储任务的一个实例,然后再使用它。
lazy
块不会阻止可为空的情况。