gpt4 book ai didi

java - volatile 引用是在线程之间传递 MotionEvents 的安全方式吗?

转载 作者:太空宇宙 更新时间:2023-11-03 11:31:24 25 4
gpt4 key购买 nike

我很好奇这种方法的安全性,我曾考虑使用这种方法在我的 Android 应用程序中传递触摸事件(并测试我对 Java 并发性的理解)。这是基础知识:

我有一个连接到 SurfaceHolder.Callback 的 SurfaceView 以获取用户输入事件,主要是 onTouchEvent 回调。调用 onTouchEvent 方法后,我查看是否 event.getAction() == MotionEvent.ACTION_UP,如果是,则调用我命名为 postTouchEvent< 的方法 这是我的应用程序线程的成员方法,用于更新应用程序的状态并绘制到 Canvas 。

表面 View

@Override
public boolean onTouchEvent(final MotionEvent event)
{
mAppThread.postTouchEvent(event);
}

应用线程

private volatile MotionEvent mInputEvent;

public void postTouchEvent(final MotionEvent event)
{
this.mInputEvent = event;
}

@Override
public void run()
{
// while loop ...

if (this.mInputEvent != null)
{
final MotionEvent inputEvent = this.mInputEvent;
this.mInputEvent == null;

// update state based on inputEvent (not this.mInputEvent)
}

// draw to canvas
}

现在我明白了,它肯定不是原子的,但是既然我从框架接收到它后就把它当作不可变的,这行不行? (而不是同步 post 方法和 if 语句,我这样做没有问题,但我要求学习。)

这是我的想法。我知道我将有一个对该对象的有效引用,但我不确定我实际看到该对象的状态。虽然测试一切正常,但我知道线程异常是多么不常见,即使出现问题也是如此。

此外,我还可以看到一个问题:如果另一个 MotionEvent 出现,则 run() 方法中的 inputEvent 可能会被设置为与在以下情况下引用的事件不同的事件this.mInputEvent != null 已检查,但这确实不是问题。

那么,有什么我遗漏的吗?或者为了我的目的,这应该没问题吗?

最佳答案

不,这不安全,但不是出于您可能期望的原因。

ViewRoot.java, line 1841 .这是将您的 MotionEvents 分发到 View 层次结构中的代码。第 1841 行是调用 recycle()finally block 的一部分在刚刚调度的 MotionEvent 上。

MotionEvents 不会像大多数对象一样被垃圾收集,它们被合并和回收以避免在事件调度期间不必要的内存分配和垃圾收集。回收 MotionEvent 将其返回到对象池,以便稍后在需要新的 MotionEvent 时再次使用。在 recycle() 被调用后,MotionEvent 应该被认为是无效的。

您的示例代码可能最终会读取一个 MotionEvent 对象,该对象已被框架重用,现在包含完全不同的数据。

如果您计划在 onTouchEvent 返回后挂起 MotionEvent,请使用 MotionEvent.obtain(event) 克隆它.静态obtain()方法将从对象池中返回一个内容相同的新MotionEvent。

当您处理完您自己obtain()将其返回到池中的 MotionEvent 时,您应该调用 recycle()。如果您忘记了这一步,这没什么大不了的,它会变成普通的 Java 垃圾,并且框架会在需要时创建新的 MotionEvents。但是,系统可以非常快速地调度 MotionEvents,以配合这种优化可以对某些设备的性能产生重大影响。

关于java - volatile 引用是在线程之间传递 MotionEvents 的安全方式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3137270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com