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.线程池(四种)

 关于线程池,之后有空会更新到另外的博文中,希望大神们多多指点.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值