一个多线程问题的逻辑思考
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个多线程问题的逻辑思考相关的知识,希望对你有一定的参考价值。
同事给了一段代码,用来实现开始录制声音和停止录制,伪代码如下:
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的理解是存在歧义的。而第二段代码就非常明确。
暂时理解到这个层次,以后有了更深的理解再记下来。
以上是关于一个多线程问题的逻辑思考的主要内容,如果未能解决你的问题,请参考以下文章