• 1

  • 1

  • 收藏

Java多线程(2)-Thread

1星期前

Thread是什么

Thread类的每一个实例(调用了start()方法并且未结束)代表一个JVM中的线程,

注意RunnableCallable都不是线程,

当Thread.start()后,JVM中就增加了一个工人/执行流(线程)和一套方法栈。

如下图,Java的最小执行单元就是方法,每个线程都有一个方法栈,里面有一个个方法栈桢,一个方法执行完毕后,栈桢就销毁,继续执行下面的栈桢,拥有方法栈也证明它是一个存活着的线程,

Java中所有方法执行的最底层的方法栈桢,一定是XXX类的main方法或者Thread.run()方法,没有其他。

多线程问题的根源

不同的执行流的同步执行是一切线程问题的根源。

如下图,从代码层面上看,代码是由上而下书写的,常规理解程序也该由上而下的执行,

但是程序跑起来以后,确是同时两个线程在对 i进行++ 操作,有些反直觉,同时这个操作会带来冲突,可能会导致结果错误。

如下图,图中的代码会被哪一个线程执行?

答案是不确定,因为图中将一个任务提交给了一个线程池,至于这个任务具体交给谁执行,将由线程池的实现决定。

再入下图,图中的抛出异常会被main方法捕捉并打印出来吗?

答案是不会,因为main方法只能只能捕捉到由main线程中的栈桢抛出的异常,而下图中箭头所指的代码,已经属于在另一个线程中的栈桢了,这就是反直觉性。

看下图就比较好理解,因为上图中,我们开启的是一个新的线程,线程之间的栈桢是隔离的,自然无法被Main方法抓取到。

看下图,我们调用了两次sayHello,一次在Thread中调用的,一次在Main中调用,

使用jstack查看当前进程中的线程信息:

jstack 进程id, 下图可以看见一个名为main和一个名为Thread-0的线程战争中都有一个叫做sayHello的方法,这说明代码在执行过程中,并不如我们在书写代码时由上而下的顺序,而是两个线程独立去做自己的事情 互不干扰,只是在main线程中去启动了一个新线程让他做事。

总结

多线程的问题与复杂之处在于反直觉,以及执行的不确定性,他们之间各自的资源(栈桢的内局部变量等)相互独立,但是共享的资源也会产生竞争,会造成死锁、计算结果错误等一系列问题,

如果程序只有一个线程,代码执永远是串行化的,不会有死锁等问题,但是由于我们想要充分利用计算机的资源,更快的帮我们做事,就需要采用多线程,

同时也要做好使用多线程遇到的问题,后续接着再更~

免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

java

1

相关文章推荐

未登录头像

暂无评论