java多线程之看图说话

  说之前大家可以看看以下三篇博客

https://segmentfault.com/a/1190000004694556      //线程的介绍

https://segmentfault.com/a/1190000004695763      //继续介绍

https://segmentfault.com/a/1190000004710242     //线程锁等高级点的介绍

 (看了这三个博客是不是有一种清新脱俗的感觉,话说这个码农老刘也真的是个人才,写的非常好。)

   这次咱们用图画(状态图)的方式来说一下线程。

 

这个就是一个线程的主要生命周期,从新建到死亡,就绪和执行两个状态之间会有多次的转换,这些都是操作系统做的,直观表现就是多个线程一同在执行中,但是一个cpu每次只能处理一个,当一个在执行中,另一个就在就绪中,然后山水轮流转,他执行一会,你执行一会,因为非常快,看起来像并行一样,所以cpu就不用闲着,得到了高效利用(至于系统怎么分配的,可以去了解时间片)。

   当然线程的一生不可能这么平淡简单,还有很多的操作,不过都是在这条主线上延伸的:

没错,这就是阻塞状态,当你的线程满足一定条件要睡眠几秒的话(sleep),就会进入阻塞状态,或者像“我是个线程”写的等待数据库返回数据(IO),也会进入阻塞状态,就是线程0x3704进入到的那个大屋子的状态,大家都在那打牌,抽烟,睡觉,没事做。join是加入线程,就是一个线程被标记为加入他就必须执行完毕才能退出来,你只能等着他。

还有一些操作也是阻塞状态,

 

假如某些操作被上锁(synchronized ),而有两个线程要执行这个操作,比如汇款操作,那么就会上锁,当一个线程进行操作时会把锁关闭,那么其他线程执行到这里就会进入阻塞(同步阻塞),等着锁打开,然后那个上锁的线程执行完这不操作把锁打开,那么等待的那个线程就就可以进入就绪状态继续执行这步操作,

wait是Object的方法,让线程放弃锁(把锁打开)然后进入等待状态(等待阻塞),这就造成了一些问题,一既然放弃锁说明你已经拿到了锁,所以wait必须写在同步代码块中(被synchronized 的代码中)。第二个既然你放弃锁,那其他线程就可以获得锁,当你被唤醒(notify,也是Object的方法)的时候你已经没有锁了,所以你想继续操作就必须等着别人把锁打开,又进入同步阻塞状态,当然可能你直接获得锁,那直接就进入就绪状态了。

生产者和消费者模式很好的展示了wait和notify的用法,感兴趣的同学可以去了解一下。

 

 

完整的图就是这个样子,仔细观察,你发现猫腻了吗,没错,就是想进入执行状态只有一个渠道,就是从就绪状态进入,所以无论什么操作进入阻塞,都必须回到就绪状态才能被执行,为啥,因为执行权是操作系统分配的,系统会在就绪状态的线程中挑选,不是咱们自己能掌控的。所以有个简单的图是这样的:

注意事项:

synchronized 锁的是什么,一般来讲锁的是当前对象,是this,也就是说,在测试的时候有同学new了多个共享对象,调用里边的synchronized 方法,发现不生效,那是因为new的话就产生一个新对象,锁也就不是一个了,synchronized只是锁住当前的,所以我们是new多个线程,去操作“共享”对象(变量),当然还可以用锁住class对象的方法达到new多个对象也生效的方法。

好了,多线程的图解就到这里了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值