Android:要求从一个线程访问的变量在另一个线程中立即可用

Android:要求从一个线程访问的变量在另一个线程中立即可用,android,multithreading,synchronization,Android,Multithreading,Synchronization,我正在开发一个OpenGLES2.0游戏,遇到了一个问题,我希望这个问题很容易解决 基本上在我的游戏中,我只使用OpenGL提供的两个线程。这些是: 渲染线程 界面线程 我将尝试用一个简单的例子来解释: 因此,在我的UI线程上,在我的onTouchEvent方法中,我正在做一些类似这样的事情,包括一些伪代码: 然后在我的渲染线程上,我使用如下变量: @Override public void onDrawFrame(GL10 gl) { Log.v("Tag","gameIsPause

我正在开发一个OpenGLES2.0游戏,遇到了一个问题,我希望这个问题很容易解决

基本上在我的游戏中,我只使用OpenGL提供的两个线程。这些是:

渲染线程 界面线程 我将尝试用一个简单的例子来解释:

因此,在我的UI线程上,在我的onTouchEvent方法中,我正在做一些类似这样的事情,包括一些伪代码:

然后在我的渲染线程上,我使用如下变量:

@Override
public void onDrawFrame(GL10 gl) {

    Log.v("Tag","gameIsPaused Value is (from Rendering Thread): "+gameIsPaused);

}
因此,“renderer”是我的GLSurfaceView,“gamespaused”布尔标志是GLSurfaceView类的成员。我只是尝试从我的UI线程更新它

当我运行代码并按下退出按钮时,有时会得到以下结果:

GameSPaused值来自UI线程:False

GameSPaused值来自渲染线程:True

这里的代码简化了,但我希望它能解释这个问题。我猜这与两个线程访问同一个变量有关,但是,我真的不确定如何解决这个问题。在这样的设置中搜索此类问题时,我看到的大多数帖子似乎都关注渲染和更新线程之间的同步,但是,正如您所看到的,我只使用一个线程进行渲染和更新,因此,我的问题特别涉及确保在UI线程上对变量执行某些操作后,这些变量立即可用于呈现线程

我试图将gameIsPaused变量标记为volatile,但是,这没有任何区别


希望有人能解释这是如何工作的,我应该做什么来避免这个问题,为什么

这是因为两个线程并行运行,但不能保证不同线程之间的操作顺序,任何线程都可能随时中断,使日志打印看起来不正常:

渲染线程读取GameSpaused变量值true 渲染线程准备字符串GameSpaused值来自渲染线程:True 线程开关 UI线程将GameSpaused变量设置为false UI线程准备字符串GameSpaused值来自渲染线程:False UI线程打印其字符串 线程开关 渲染线程打印其字符串 其他可能性:

渲染线程读取GameSpaused变量值true 线程开关 UI线程将GameSpaused变量设置为false UI线程准备字符串GameSpaused值来自渲染线程:False UI线程打印其字符串 线程开关 渲染线程准备字符串GameSpaused值来自渲染线程:True来自寄存器值 渲染线程打印其字符串 如果需要在设置多个变量时同时设置多个变量,而渲染线程不运行,则需要使用互斥锁来防止在更改变量时渲染线程运行

另一个选项是在UI线程中设置单个变量,并让渲染线程执行设置多个变量的工作

第三个选项是准备一个消息对象,并使用消息队列将其发送到渲染线程,以便渲染线程将其作为单个操作来处理


其中任何一项都将确保渲染线程不会看到中间状态,其中一些变量已更新,另一些变量已使用其旧值。

非常感谢@StephaneHockenhull,很有趣。当你说使用互斥时,你是在说使用同步块吗?另外,请你解释一下第二个选项,我不太明白你所说的多个变量是什么意思-我只更新了一个变量?如果你是第三种选择,我猜你指的是排队事件?是否可以编辑您的答案以显示一些简短的代码示例,以便我能更好地理解,谢谢-感谢您的帮助!在这种情况下,是的,一个同步块可能就足够了。谢谢@StephaneHockenhull,我将尝试将对变量的访问封装在一个同步块中
@Override
public void onDrawFrame(GL10 gl) {

    Log.v("Tag","gameIsPaused Value is (from Rendering Thread): "+gameIsPaused);

}