如何处理android中UI线程和另一个线程之间共享的变量?

如何处理android中UI线程和另一个线程之间共享的变量?,android,multithreading,Android,Multithreading,我正在尝试在android上开发一个与音频处理相关的应用程序。我有一个线程(不是UI线程)在其中执行操作。我需要在操作仍在进行时更新操作的结果。同样,我使用了一个处理程序。我只是使用Toast在处理程序中显示结果。到目前为止,我的线程第一次单独运行,在显示第一个结果后,线程不再运行,因为结果不会更新。我刚刚知道,在修改这个线程和UI共享的变量时,我需要同步这两个线程。我说得对吗?如果是的话,我怎样才能做到呢 谢谢 编辑 我正在发布在我的线程和处理程序中运行的方法的一部分 whil

我正在尝试在android上开发一个与音频处理相关的应用程序。我有一个线程(不是UI线程)在其中执行操作。我需要在操作仍在进行时更新操作的结果。同样,我使用了一个处理程序。我只是使用Toast在处理程序中显示结果。到目前为止,我的线程第一次单独运行,在显示第一个结果后,线程不再运行,因为结果不会更新。我刚刚知道,在修改这个线程和UI共享的变量时,我需要同步这两个线程。我说得对吗?如果是的话,我怎样才能做到呢

谢谢

编辑

我正在发布在我的线程和处理程序中运行的方法的一部分

        while(fulldatabuffcnt+200<=fulldatabuffer.size())  
        {   
            double[] windowdata=new double[200];
             classlabel=0;
             //classlabel_new=0;
             int windowcnt=0;
                for (int h=fulldatabuffcnt;h<fulldatabuffcnt+200;h++)
                {
                        windowdata[windowcnt]=fulldatabuffer.get(h);
                        windowcnt++;
                }

                MFCCcoeffs=mfcc_inst.getParameters(windowdata);
                classlabel=likeli_ref.llhmain(MFCCcoeffs);

            try {
                out.writeInt(fulldatabuffer.size());

                } catch (IOException e1) 
                {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

            classlabel_array[ecount]=classlabel;
            ecount++;

            if (ecount==25)
                {
                      synchronized(SharedData.globalInstance) {

                            SharedData.globalInstance.classlabel_new =occurence(classlabel_array);//<--shared variable classlabel_new getting modified
                        }
                      try {
                            out_max.writeInt(SharedData.globalInstance.classlabel_new);
                            } catch (IOException e1) {
                                // TODO Auto-generated catch block
                                e1.printStackTrace();
                            }

                      ecount=0;
                     uiCallback.sendEmptyMessage(0);


                }


        fulldatabuffcnt=fulldatabuffcnt+80;
        }
       if(fulldatabuffcnt+200>fulldatabuffer.size()){

           AppLog.logString("Setting calclating thread to null");
           calculatingThread = null;
       }
       try {
           out.close();

           out_max.close();
        } 
       catch (IOException e) 
        {
           e.printStackTrace();
        } 

   }


   private Handler uiCallback = new Handler () {

         public void handleMessage (Message msg) {
            int label_handler;
            synchronized(SharedData.globalInstance) {
               label_handler=SharedData.globalInstance.classlabel_new;
            }

             Toast.makeText(MFCC2Activity.this, "Classified label" +label_handler, Toast.LENGTH_SHORT).show();//<--trying to access classlabel_new

         }

     };

while(fulldatabuffcnt+200是,您应该同步以确保您的UI线程不会访问仅由您自己的线程部分设置的变量

我建议您有一个singleton对象,其中包含两个线程之间需要传递的所有变量/数据等。例如,假设您需要在自己的线程和UI线程之间共享一个字符串和一个double。使用singleton创建一个类SharedData,例如

class SharedData {
    public String aString;
    public double aDouble;
    public static SharedData globalInstance = new SharedData();
}
然后在您自己的线程中设置数据

synchronized(SharedData.globalInstance) {
    SharedData.globalInstance.aString = "some string";
    SharedData.aDouble = 42.0;
}
在你的UI线程中

String aString;
double aDouble;
synchronized(SharedData.globalInstance) {
    aString = SharedData.globalInstance.aString;
    aDouuble = SharedData.aDouble;
}
// do something with aString and aDouble

如果您这样做,那么就不会出现与UI线程读取部分设置数据相关的任何问题。

感谢您的快速响应。我按照您所说的做了,但仍然没有更改。请检查我所做的编辑。classlabel\u new是在线程中修改的变量,该线程将与han共享据我所知,如果使用线程安全的方式共享名为classlabel_new(SharedData类的一个字段)的int,你会怎么做。我不确定你的代码到底要做什么,但我很确定,如果它仍然没有达到你想要的效果,这不是与同步相关的问题。好的。我不知道我是否能够让你完全理解这种情况,但现在发生的事是,每当检测语音活动时,缓冲区fulldatabuffer就会被填满在通过麦克风进行的录制中被选中。此步骤由另一个线程完成,上面代码中显示的此线程对fulldatabuffer进行某种处理。每当我对显示部分进行注释时,即uiCallback.sendEmptyMessage(0);一切都在完美地进行。但是当我把它包括进来,在第一个声音之后,每当沉默来临,即当fulldatabuffer停止被另一个线程更新时,这个线程停止运行。你知道问题的原因是什么吗?也许你应该发布另一个问题来关注这个问题,因为你在这里发布的问题只是关于线程之间的同步。但下面是我要做的调查。我在日志中放了很多
Log.d(…)
everywhere,以便准确了解所有线程的路径以及失败的位置。如果您再次发布,请发布所有线程的所有信息以及所有错误消息。很抱歉,我无法提供更多帮助。