子线程运行10次后,主线程运行100次,子主交叉运行。如此循环50次。

很多同学写这个代码时容易写迷糊。其实只要经过下面几个步骤的分析,你会发现这个问题很简单。

1 理清循环50次和子线程运行10次,主线程运行100次,不要交叉在一起

循环50次可以看作是调用方操作,调用方可以选择操作50次,也可以选择操作100次。

子线程和主线程可以看作被调用方接口,调用方只要调用我了,我就执行xxx次(子线程运行10次,主线程运行100次)。

2 注意一点:

    子线程运行第一个十次完成前,主线程是不允许运行的,且子线程也不允许运行第二个十次操作。例:调用方第一次调用时,子线程第一个十次调用运行到了第8次。这时子线程持有锁,主线程是进不来的,但是子线程是可以进来的,这就导致如果不做处理,调用方调用子线程进行第二个十次运行,子线程的第一次十次运行和第二次十次运行混在一起,需要怎么处理呢?答案是线程通信。可以使用wait(),notify(),也可以使用java.util.concurrent.locks.Condition。

有了上面的清晰思路代码就好写了。

3 重入锁

为什么子线程的第一次十次运行和第二次十次运行混在一起?第一个十次运行的锁为什么可以第二个十次仍然可以执行?

synchronized可重入性

同一线程在调用自己类中其他synchronized方法/块或调用父类的synchronized方法/块都不会阻碍该线程的执行,就是说同一线程对同一个对象锁是可重入的,而且同一个线程可以获取同一把锁多次,也就是可以多次重入。点击打开链接

重入锁

(1)重进入:

1.定义:重进入是指任意线程在获取到锁之后,再次获取该锁而不会被该锁所阻塞。关联一个线程持有者+计数器,重入意味着锁操作的颗粒度为“线程”。

2.需要解决两个问题

线程再次获取锁:锁需要识别获取锁的现场是否为当前占据锁的线程,如果是,则再次成功获取;

锁的最终释放:线程重复n次获取锁,随后在第n次释放该锁后,其他线程能够获取该锁。要求对锁对于获取进行次数的自增,计数器对当前锁被重复获取的次数进行统计,当锁被释放的时候,计数器自减,当计数器值为0时,表示锁成功释放。

3.重入锁实现重入性:每个锁关联一个线程持有者和计数器,当计数器为0时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为0,则释放该锁

下篇:http://blog.csdn.net/wabiaozia/article/details/79534560


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值