gpt4 book ai didi

android - 处理程序/可运行延迟有时会产生不同步的事件

转载 作者:太空狗 更新时间:2023-10-29 14:26:40 28 4
gpt4 key购买 nike

在尝试学习如何创建延迟时,我进行了研究并发现主要答案是使用 Handler/Runnable/postDelayed。

                        Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
delayedMethod();
}
};
handler.postDelayed(r, 1000);

这在一段时间内工作正常,但我又添加了一些正在发生的事情,现在它们有时会以错误的顺序发生。

这组事件:

paintScreen1()
...
delayedPaintScreen2()
...
paintScreen3()

搞砸了(有时)并这样做:

paintScreen1()
...
paintScreen3()
...
delayedPaintScreen2()(最后运行并被 paintScreen3 的 Action 弄乱)

似乎没有另一种创建延迟的好方法 - 一种不创建线程的方法。

为了确保代码事件以正确的顺序运行,我尝试过的解决方案:

0 将主进程放在一个大的同步块(synchronized block)中。

1 将synchronized关键字放在主进程涉及的每个方法的方法名中。

2 仅将 synchronized 关键字放在 Runnable 中的方法上。

3 去掉 Handler/Runnable/postdelayed 并替换为 handler.sendEmptyMessageDelayed(0,1000)

4 创建一个 Handler 实例变量,供每个 Handler/Runnable block 使用(与 Handler handler1、handler2、handler3 等相对)

5

                        Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
waitOver = true;
}
};
handler.postDelayed(r, 1000);

while (waitOver == false) {

}
delayedMethod();
waitOver = false;

我的下一次尝试可能是尝试以某种方式使用 Thread 类,以便我可以调用 thread.join()。如果失败,接下来的事情将非常漫长和复杂,我担心。

有什么建议吗?

任何简单的解决方案示例?

谢谢

编辑:我可能对 Handler/Runnable 是否会导致文字线程感到困惑。

编辑:这是一个游戏。用户移动,屏幕更新以显示移动,计算表明他们得分了,重新为屏幕上的框着色,添加延迟以允许用户看到他们的点,然后调用方法删除彩色方 block ,当该方法完成并我们返回调用它的方法(包含 Handler/runnable),代码继续向下调用另一个方法,该方法导致棋盘的随机方 block 变成紫色。所以它应该发生用户移动,重绘以显示得分,延迟以便用户可以看到得分,重绘以删除方 block ,然后随机紫色方 block 发生。有时会发生什么(据我所知)是随机的紫色方 block 会在它应该执行之前执行,选择得分的方 block 之一,干扰,然后清理方法变得困惑并且无法清理。

主要方法(){
...
如果(得分){
squaresglow();
...
//延迟以便用户可以在清理发生之前看到发光
处理程序可运行
清理(​​);
后延迟

...
紫色方 block ();
}

我希望这不会更加困惑。 purpleSquare 在清理之前运行,事情搞砸了。

编辑:试过这个:6

                        CountDownLatch doneSignal = new CountDownLatch(1);
Handler handler=new Handler();
final LatchedRunnable lr = new LatchedRunnable(doneSignal);
handler.postDelayed(lr, COMPUTER_MOVE_DELAY);
try {
doneSignal.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

class LatchedRunnable implements Runnable {
private final CountDownLatch doneSignal;

LatchedRunnable(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}

public void run() {
delayedProcess();
doneSignal.countDown();
}
}

7

                        ExecutorService executorService = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(1);
executorService.execute(new Runnable() {
public void run() {
try {
Looper.prepare();
Handler handler=new Handler();
final Runnable r = new Runnable()
{
public void run()
{
delayedMethodCleanupCalc();
}
};
handler.postDelayed(r, 4000);
} finally {
latch.countDown();
}
}
});
try {
latch.await();
delayedMethodPaintScreen();
} catch (InterruptedException e) {
// todo >> handle exception
}

最佳答案

purpleSquare runs before cleanup and things get screwed up

mainmethod() {
...
if (pointscored) {
squaresglow();
...
//delay so user can see the glow before the cleanup happens
Handler-runnable
cleanup();
postdelayed
}
...
purpleSquare();
}

你这里有一个设计缺陷。将 Handlers 视为一个消息队列,只要处理器决定处理消息,它就会“稍后”执行代码,将 postDelayed 视为将该消息填充到队列底部的一种不准确的方式。如果您调用 postDelayed 并且当前方法中仍有代码行要执行,那么这些行很有可能会在收到 postDelayed 消息之前执行。

您要做的是确保在 pointscored 例程完成其工作后调用 purpleSquare(),这可能需要等待它完成。在这种情况下,PostDelaying 到消息队列不是你应该做的。您应该使用的是信号量和 pointScored 线程。

考虑以下代码设计:

final Runnable pointScoredTask = new Runnable() {
public synchronized void run() {
try {
squaresglow();
//...
Thread.sleep(2500); //2.5 sec before cleanup occurs
cleanup();
} catch (InterruptedException e) {
}
notify(); //make sure we call notify even if interrupted
}
};
void mainmethod() {
//...
if (bPointWasScored) {
synchronized (pointScoredTask) {
try {
Thread psThread = new Thread(pointScoredTask,"pointscored");
psThread.start(); //thread will start to call run(), but we get control back to avoid race condition
pointScoredTask.wait(6000); //wait no more than 6 sec for the notify() call
} catch (InterruptedException e) {
}
}
//if a point was scored, nothing past this line will execute until scoreglow has been cleaned up
}
//...
purpleSquare();
//...
}

我知道您宁愿避免线程,但有些东西在您使用它们时会工作得更好。试试上面的设计,看看是否能解决您遇到的同步问题。

关于android - 处理程序/可运行延迟有时会产生不同步的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11787523/

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