一个多线程问题的逻辑思考

同事给了一段代码,用来实现开始录制声音和停止录制,伪代码如下:

 1 void StartRecord()
 2 {
 3   new Thread()
 4   {
 5     void run()
 6     {
 7       m_isRecording = true;
 8       Java_StartRecord();
 9       while(m_isRecording == true)
10       {
11         Java_RecordCallback();
12       }
13     }
14   }
15 }
16 
17 void EndRecord()
18 {
19   m_isRecording = false;
20 }

StartRecord函数开启录制线程,通过m_isRecording 来设置录制状态。

初一看这里没什么问题,并且大多数情况下也确实可以正常工作。但是对于特殊的情况,比如StartRecord之后很快调用EndRecord,这时候StartRecord创建了录制线程,但是录制线程还没有开始执行。由于线程调度的不确定性,EndReocord确实存在在录制线程前执行的情况。这种情况下,EndRecord把m_isRecording 设置为了false,而录制线程在执行的时候又把m_isRecording 设置成了true,这就回导致录制线程永远不会结束。解决这个问题的办法是改成下面的代码:

 1 void StartRecord()
 2 {
 3    m_isRecording = true;
 4     new Thread()
 5     {
 6       void run()
 7       {
 8        Java_StartRecord();
 9        while(m_isRecording == true)
10        {
11          Java_RecordCallback();
12        }
13      }
14    }
15 }
16  
17 void EndRecord()
18 {
19    m_isRecording = false;
20 }

这样虽然解决了问题,但也应该进行更深入的思考。其关键就在于m_isRecording的意义。这里涉及到了两个客体,一个是主线程(调用StartRecord和EndRecord的线程),另外一个是录制线程。在第一段代码中,EndRecord函数中认为m_isRecording标识主线程的状态,因为只有主线程才会调用EndRecord函数病修改m_isRecording的值。但是在StartRecord函数中却是录制线程修改了m_isRecording的值,同时又在录制线程中读取m_isRecording。录制线程认为m_isRecording表示的是录制线程的状态。所以在第一段代码中,对m_isRecording的理解是存在歧义的。而第二段代码就非常明确。

暂时理解到这个层次,以后有了更深的理解再记下来。

posted on 2017-09-30 19:47  zhangshuliai  阅读(363)  评论(0编辑  收藏  举报