首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何同步2个异步线程/任务

如何同步2个异步线程/任务
EN

Stack Overflow用户
提问于 2017-05-08 17:41:27
回答 1查看 66关注 0票数 0

对于我的应用程序,我必须运行两个操作,两个操作都是异步的:

  1. 从文件中读取(我使用这个文件来模拟从数据总线读取)-异步操作,因为我不知道“何时”到达总线上的新消息/字符。我搜索一个特定的序列字符,例如frame start_bytes = "xx“,下面的4个字节是我等待的”数据“。
  2. 将数据读取/更新到Firebase,这取决于由于使用addValueEventListener而从文件-异步操作读取的“数据”。

我正在考虑一个信号量/互斥机制,或者一个简单的布尔标志,即一个任务向另一个任务发出信号,一个新数据必须保存/更新到Firebase。

如何同步这两个操作(通过将它们嵌入任务/ AsyncTask /线程中)?

我搜索了这些主题,但是我找到了与UI、ProgressBars等相关的例子。不太适合我的处境。

读取/更新Firebase中的数据

代码语言:javascript
运行
复制
   myRefDevices.addValueEventListener(new ValueEventListener() {
                //  addValueEventListener
                // This method is called once with the initial value and again
                // whenever data at this location is updated.
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    boolean             bChildFound         = false;
                    DatabaseReference   dbrefChildFound;

                    final CDeviceStatus obj_new = new CDeviceStatus();

                    for( DataSnapshot val : dataSnapshot.getChildren() )
                    {
                        if( val.getKey().contentEquals(MAC_ADDRESS[ iIterator ]) )
                        {
                            bChildFound = true;

                            dbrefChildFound = val.getRef();

                            obj_new.setiAvailable_A( val.getValue( CDeviceStatus.class ).getiAvailable_A() + 1 );

                            obj_new.setsID(val.getValue( CDeviceStatus.class).getsID() );

                            dbrefChildFound.setValue(obj_new);
                        }
                    }

                    if(!bChildFound)
                    {
                        Log.d("child=" + MAC_ADDRESS[ iIterator ], "not found");
                    }


                    if(++iIterator == 16)
                    {
                        iIterator = 0;
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }

            });

从档案中读取:

代码语言:javascript
运行
复制
try {
    // open input stream text file for reading
    Resources res = getResources();
    InputStream instream = res.openRawResource( R.raw.simulated_bus );

    //  we convert it to bufferred input stream
    BufferedInputStream bistreamSimulatedBus = new BufferedInputStream(instream);

        try{
            // if we want to stop reading from the file / simulated bus for whatever reason..
            boolean bStayInLoop         = true;

            while ((bistreamSimulatedBus.available() > 0) && bStayInLoop)
            {
                try {
                    // throw new InterruptedException();
                    char c = (char) bistreamSimulatedBus.read();

                    if( COUNT_CHARACTERS_NEWLINE )
                    {
                        if ( '\n' == c ){
                            //  we can count how much NewLine character we have
                            //iNL_Counter++;
                        }
                    } 

                ...

                }
                catch ( InterruptedException e ) {
                    throw new RuntimeException( e );
                }
            }
        } catch (IOException e) {
                throw new RuntimeException( e );
        } 
        finally {
                // release any resource associated with streams
                if ( null != instream ) {
                    instream.close();
                }

                if ( null != bistreamSimulatedBus ) {
                    bistreamSimulatedBus.close();
                }
            }
        }
    catch (Exception e) {
        throw new RuntimeException( e );
    }

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-05-08 18:13:04

让我们像这样打破这个解决方案:

基础

您有两个操作:o1o2。您希望在第一个操作完成后立即执行第二个操作。

在我看来,显然是,这里需要一个event-driven解决方案。

逼近

使用Publisher/Subscriber设计模式的概念,您可以使Initiator of o1成为事件的Publisher。然后,当这个特定的操作o1完成时,让类(活动、片段、服务) notify为另一个类,我们称之为Subscriber

将以下一行添加到您的build.gradle (app-level)

代码语言:javascript
运行
复制
compile 'org.greenrobot:eventbus:3.0.0'

然后,只需创建一个简单的Plain Old Java Object (POJO)来表示您的事件。

代码语言:javascript
运行
复制
public class RequestCompletedEvent{ // add constructor and anything you want}

接下来,要对事件进行Publish,只需按如下方式调用post(POJO instance)

代码语言:javascript
运行
复制
EventBus.getDefault().post(new RequestCompletedEvent(true));

最后,在Subscriber类中,只需通过添加以下代码行来侦听通知:

代码语言:javascript
运行
复制
@Override
public void onStart() {
  super.onStart();
  EventBus.getDefault().register(this);
}

@Override
public void onStop() {
  super.onStop();
  EventBus.getDefault().unregister(this);
}

然后仍然在同一个类中,使用Subscribe注释捕获任何信号:

代码语言:javascript
运行
复制
@Subscribe
public void onEvent(RequestCompletedEvent event) {
   /* Do something */
   //trigger the second operation here;
  startOperationTwo();
}

摘要

这里需要注意的是,实现此操作的最简单方法是使用async任务(AsyncTask子类)读取您的文件,然后在onPostExecute()中成功完成后,您可以通知Subscriber启动下一个操作。

我希望这能帮上忙,祝你好运!如果你需要进一步的帮助,请告诉我!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43854004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档