这里说一个观点:线程的可见性和语言无关,即任何语言都需要考虑线程可见性带来问题
一、java
public class Main {
public boolean b = true;
public void m() {
System.out.println("start");
while(this.b){
}
System.out.println("end");
}
public static void main(String[] args) throws Exception{
Main main = new Main();
new Thread(new Runnable() {
@Override
public void run() {
main.m();
}
}).start();
Thread.sleep(5000);
main.b = false;
}
}
代码说明:通过new Thread创建一个线程,这个线程执行m()方法,m方法是一个死循环。主线程睡眠5秒,将成员变量b设置为false以此来终结线程。然而结果线程并没有被终结
二、c语言
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int running = 1;
void* start_thread(void *data ) {
printf("thread started\n");
while(running) {
}
printf("thread will be exited\n");
}
int main() {
pthread_t t;
pthread_create(&t, NULL, start_thread, NULL);
sleep(5);
running = 0;
pthread_join(t, NULL); //等待线程t结束
}
C语言场景需要在编译的时候才能模拟出来:
gcc a.c -O3 -lpthread ---> 结论,O1,O2,O3,开启优化,线程不退出
gcc a.c -lpthread ---> 结论不优化,线程退出
通过以上实验,可知线程可见性是和语言无关的。那么应该如何解决呢,使用volatile进行修饰,volatile作用:线程可见性和禁止重排序