不知不觉敲代码断断续续也已经有半年的时间了,今天在回顾线程特别是多线程的时候发现了一些问题,废话不多说直接上代码。
如下图新建了两个相同的代码,他们同时调用了一个方法。
public class ThreadTest1 {
public static void main(String[] args) {
Test test =new Test();
new Thread(() ->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() +":"+test.getI() );
}
}).start();
new Thread(() ->{
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() +":"+ test.getI());
}
}).start();
}
}
class Test{
private int i;
public int getI(){
return this.i++;
}
}
粘一张运行结果图
以前有个问题是,代码不是按行顺序运行的吗,那为啥会出现红框内的线程1出现在线程0前面的问题呢?
好问题
代码是不会骗人的,代码具体怎么执行我们完全可以使用debug的方法来查看,因为无法上传视频,因此我在这里简单讲一下他的执行过程,我们在运行到线程0的时候,通过start()方法来开启这个线程,此时,相当于开创了一个新的空间,让里面的遍历代码执行getI()方法。
注意!此时,我们的调试箭头是进不了for循环里面的。这也印证了上述描述。
在执行过程中我们来到了下一个Thread然后再次start(),这样我们就又开辟了一块空间来执行里面的遍历代码,因为线程0里面的遍历需要时间,可能在运行到线程1的时候我们的线程0就已经运行结束了,所以如果循环i的值过小就很有可能被误以为两个线程是同步进行。我们把i设置为10,当线程1开始执行的时候线程0还未执行完毕,因此两者是同时进行遍历的。他们在执行过程中不断调用同一个方法,两个线程是同样的优先级,他们的调用顺序是随机的。具体怎么做cpu说了算。因此就出现了代码的执行结果。
2.多线程,并行,并发,同步,异步 之间联系他们是干啥的
首先简述一下概念
同步&异步
比如说我是小马云
两个行为
吃饭 看电视
场景1妈妈在家的时候
同步 :即先后顺序先吃完饭再看电视
场景2 妈妈不在家的时候
异步 : 我一边看电视一边吃饭。
理解清楚概念之后:
对于多线程来讲: 两个线程很明显是异步进行的,
但是他们的行为是同步的,因为调用方法只能一个线程调用之后,另一个线程再次调用。
并行&并发
并行: 两个线程可以在同一时刻调用方法,需要用到线程池+future(这个牵扯的有点多以后再说)(比如多核CPU 同时处理多个任务)。
并发: 并发就是我这几个线程启动了都在运行,但是同一个时刻只有一个线程在运行(即在调用方法)