java多线程理解总结:
进程等于在运行的java程序
而线程是进程下的一个子任务,与进程共享内存空间,文件句柄等
线程是进程的组件,是java代码的最小单位
线程分为守护线程与用户线程
守护线程:
为其他小程序运行提供服务的线程比如gc线程,用户线程全部关闭后,没有服务对象,所以守护线程也没啥作用,随着jvm关闭了,比如我以前做的redis消息队列的守护线程,jvm关闭守护线程就一定会退出
用户线程:
如果停止jvm.用户线程需要全部关闭(如果没有关闭可导致jvm无法停止,进程依然留存)
状态 :
new:线程刚创建时的状态,只会存在一次
runnable:复合状态包括ready跟Running,ready表示线程可以被jvm的调度器调度让他变为running状态
running表示进程正在运行,如果运行yield,该进程会让出cpu时间,让其他或者自己的线程继续执行,执行yield线程会进去ready状态
集合
blocked:发起阻塞式io操作后,常见的是被线程锁锁住,尝试去获取该锁时的状态,如果io操作完成,或者锁被释放,获取到式会转变为runnable
waiting:一个线程执行某些操作比如wait会释放当然得锁,使当前的线程进入等待状态,而当notify或者notifyall时才会唤醒一个或多个等待的线程,但是不代表当前就在运行,因为不会立即释放锁,要看代码是怎么写的
timewaiting:跟waiting.差不多但是是有等待时间的,时间过后就转换为runnable
terminated:结束状态,有且一次
上下文切换:除了只有一次的new跟terminated,其他的几个状态切换都属于上下文切换(只要切换就会有资源开销) ,借鉴其它大牛的说法,线程间的切换,状态变化需要对相应的上下文信息进行保存和恢复(会带来资源消耗),这个过程就被称为上下文切换。
jvm监控工具
- jvisualvm(本人在windows下开发常用)、jstack、JMC
synchronized和volatile
推荐看一下csdn这个大佬的文章:https://blog.csdn.net/weixin_41209870/article/details/80954057
原子性:
原子操作是指相应的操作是单一不可分割的操作。
内存可见性 :
比如多线程时,A线程读取count的值,cpu运行时会把count的值缓存到cpu的缓存区,此时值的修改可能只是在缓存区进行变动,而此时B线程读取count的值可能会不准确,也就是count修改后的值变为了不可见,这个情况就叫做内存可见性.
重排序:
简而言之就是你预想的代码执行操作与实际出现偏差.比如多线程时,object obj=new object(),这个时候由于多线程,A在创建时,B就引用,而B线程访问obj时其实是一段内存地址,而obj可能还在初始化中,这时就会出现异常.
synchronized:
实现操作的原子性,其本质是通过该关键字所包括的临界区(Critical Section)的排他性从而保证在任何 一个时刻只有一个线程能够执行临界区中的代码,这样就使得临界区中的代码代表了一个原子操作.既然同一时刻只有一个线程能够执行相应代码,那么内存可见性也得到了保证.可以理解为,顾客去点菜,一个顾客,但是有N个大厨,哪个大厨先看到菜单,就由哪位大厨做菜,而且理论上效率也得到保障,因为大厨的数量是N个.
volatile:
无法保证原子性,但是他可以禁止重排序,volatile背后就是在cpu把count写到cpu缓存时,让count的值也写到内存中,无论什么时候其它线程获取count的时候都是最新的,但是他无法保证该值被修改,所以他不支持原子性.
总结:
synchronized关键字技能保证操作的原子性,也能保证内存可见性,但是会导致上下文切换。volatile关键字仅能保证内存可见性。
多线程优缺点
优点:
资源利用率更好,程序设计在某些情况下更简单,程序响应更快(例如可以启多线程做异步操作,比如异步入库,异步调用短信接口之类的) ,还有一点就是充分利用了多核cpu的资源
缺点:
某些业务下,设计多线程时会更加复杂,而且往往需要更加注意读取共享数据时的操作.业务处理上如果不够优化,在启用多线程时因为线程之间的切换,会带来额外的开销,在没必要时应该减少上下文切换的情况发生.
使用时应该解决的问题:
- 如何优雅的停止线程
- 线程间协作
- 业务上提高并发性
- 业务上提高响应性
- 减少资源消耗
JAVA启动线程的四种方式:
1.extends Thread
2.implements Runnable(使用说明:new Thread(放进去该线程))
3.implements Callable(可以有返回值,new Thread(放进去该线程))
4.线程池(四种)
关于线程池,之后有空会更新到另外的博文中,希望大神们多多指点.