不同线程之间代码块的序列化

Posted

技术标签:

【中文标题】不同线程之间代码块的序列化【英文标题】:serialization of code blocks between different threads 【发布时间】:2012-03-06 19:17:24 【问题描述】:

我正在android上制作一个游戏,它将有三个线程。这些将是我的 GL 渲染线程、我的游戏更新线程和 UI 线程。

游戏围绕“球”对象的ArrayList(以及常规数组)展开。用户通过点击屏幕创建一个球,游戏更新线程在屏幕上移动球,渲染线程绘制所有球。

我遇到的问题是处理由许多线程访问相同数据(即球数组)引起的并发问题。一个特别的问题是当游戏线程移除球并且渲染线程尝试访问移除的球时收到out of bounds exception

如果您考虑一下我发布的代码示例。确保一旦这些代码块中的任何一个(在不同线程上)开始执行,另一个在完成之前无法启动的最佳方法是什么?

渲染线程

int size = balls.size();
for(int i = 0; i < size; i++)
      Ball ball = balls.get(i);
      drawBall(ball.xCoord, ball.yCoord, ball.image);

游戏广告

int size = balls.size();
for(int i = size -1; i >= 0; i--)
    Ball b = balls.get(i);
    b.updateBallPosition();
    b.updateBallVelocity();

    if(b.isOutOfBounds())
        balls.remove(i);

【问题讨论】:

这段代码还能编译吗? int 没有任何方法updateBallPosition 是的,它不会。我在复制时犯了一个错误。 【参考方案1】:

使用synchronized 块来确保部分代码互斥:

final Object lock = new Object(); // globally visible lock object

渲染线程:

synchronized(lock) 
   int size = balls.size();
   for(int i = 0; i < size; i++)
         Ball ball = balls.get(i);
         drawBall(ball.xCoord, ball.yCoord, ball.image);
   

游戏线程:

synchronized(lock) 
   int size = balls.size();
   for(int i = size -1; i >= 0; i--)
       i.updateBallPosition();
       i.updateBallVelocity();

       if(i.isOutOfBounds())
           balls.remove(i);
   

此时,两个线程中只有一个可以执行代码,而另一个会阻塞。请注意,它们必须在同一个锁对象上同步。

【讨论】:

以上是关于不同线程之间代码块的序列化的主要内容,如果未能解决你的问题,请参考以下文章

如何在一组行之后或有条件地在没有 PL/SQL 块的情况下增加 oracle 序列?

bzoj3744 Gty的妹子序列

IPC机制总结

SQL 检索具有不同序列号的所有记录,在日期范围和计数之间,拒绝代码 = "Low Current"

Perl:在线程之间共享复杂的数据结构

异步和同步的区别?