android中的两个并发异步任务-如何处理竞争条件?

2ledvvac  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(401)

每次按下按钮和释放按钮时,我都会发送一个http post。在释放按钮之前,我很可能不会收到“按下”帖子的响应,因此我尝试同时运行这些任务。但是,有时,释放按钮的post请求会在请求按下按钮之前发送到服务器。我怎样才能避免/解决这个问题?

button = (ImageButton) findViewById((R.id.button1));
        button.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                HTTPAsyncTask task = new HTTPAsyncTask();
                if (event.getAction() == MotionEvent.ACTION_DOWN ) {
                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Utilities.StringCollection.rotateRight);
                    return true;
                }
                else if (event.getAction() == MotionEvent.ACTION_UP){
                    task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Utilities.StringCollection.stop);
                    return true;
                }
                return false;
            }
        });
ifsvaxew

ifsvaxew1#

从概念上讲,你的
HTTPAsyncTask doInBackground() 由两个不同的操作组成:
连接,并将请求排队到套接字
接收响应
(当然,在那之后, onPostExecute() 将被调用。)
如前所述,您需要控制操作1在两个不同线程上的执行顺序,同时允许操作2并行执行。
这不可能使用泛型 AsyncTask 机制,因为您没有提供任何“将任务一分为二”的方法;线程a无法判断线程b何时从操作1切换到操作2,反之亦然。
可以添加这样的逻辑,但是您没有解释如何进行套接字调用。
但是,提供这些额外的细节没有什么意义;与网络请求相关联的边缘案例会破坏您可能拥有的任何订单保证。网络有损;请求可能失败,响应可能失败。即使请求是按顺序发送的(特别是在使用两个单独的套接字时),请求也可能会按顺序到达。自动重试可能需要几秒钟才能完成。
瞧,“按下”的请求可能会被网络丢失,在“未按下”的请求完成后,您可能需要将其重新排队到套接字。
我建议您放弃正在寻求的“部分条件并发”,只需确保 HTTPAsyncTask 在执行第二个之前已完成。
或者,您可以向每个post添加一个连续的“request id”,或者在第二个请求中包含关于第一个请求的信息,这样服务器就可以整理出发生了什么,即使请求到达的顺序不对。

xbp102n0

xbp102n02#

如果您的min sdk是11“honeycomb”,您可以像这样调用asynctask以在单线程中运行它,以防止它们之间出现争用情况:

button = (ImageButton) findViewById((R.id.button1));
        button.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                HTTPAsyncTask task = new HTTPAsyncTask();
                if (event.getAction() == MotionEvent.ACTION_DOWN ) {
                    task.execute(Utilities.StringCollection.rotateRight);// using one thread
                    return true;
                }
                else if (event.getAction() == MotionEvent.ACTION_UP){
                    task.execute(Utilities.StringCollection.stop);// using one thread
                    return true;
                }
                return false;
            }
        });

重要提示:网络i/o不可靠,网络包可能丢失或无法按发送顺序接收,但我看到了标题中的问题
“android中的两个并发异步任务-如何处理竞争条件?”
就这么回答了。因此,您无法确定是否以这种方式一个接一个地接收到请求。我建议您在一个请求中向服务器发送两个事件,并在服务器中分析它。

相关问题