创建线程有三种方式:实现Runnable接口、继承Thread类、实现CallAble接口,代码如下:
对应的运行结果如下:
有些小伙伴可能会对结果二和结果三产生疑问,现在解释如下(个人理解):
程序是调用了两个线程来并发执行(不是并行),也就是两个线程交替获得cpu的执行权来运行自己线程栈中的程序,但是他们在运行的过程中,没有办法保证自己栈中代码块的原子性,也就是没办法保证从始到终一直执行,很可能在运行到一半的时候cpu的执行权就不属于自己,于是自己进入阻塞的状态。
变量的执行需要进行三个步骤:在内存中读取、修改变量的值、将变量的值刷入内存。所以线程可能在任何一个步骤就被阻塞住了。
就拿最后一张图来做解释:可以看到callable2一共执行了3次,值分别是0 1 2.可是callable1也有一个值为2,这就是因为,当callable2在自己的内存中将i变量增加到3的时候,突然被阻塞,就是失去了cpu的执行权,从而结果2没有被刷新进入内存,这个变量值对callable1就是不可见的,所以在callable1执行的时候,在读取内存中的数据的时候i变量仍然是1,所以callable1是在i=1的情况下执行的,执行到i=3的时候遇到了跟callable2一样的情况,虽然在自己的栈内存中改变了变量的值但是主内存并没有改变。
接着callable2获得执行权,cpu恢复现场(cpu的策略),接着上次的位置继续执行,所以输出了2,而最后callable1输出了4,由于数据的不可见导致多运行一次。
希望我的解释可以帮助不懂得小伙伴走出困惑。有不对的地方欢迎大家指出!