讲一讲线程通信

线程之间的通信主要由四种形式

文件通信,指的是线程之间通过同一个文件的修改进行互相协作通知

网络通信, 指的是线程之间通过网络传输信息进行协作通信

变量通信,指的是线程之间通过共享内存的同一个变量进行修改达到互相协作通知的目的

java api通信,又主要分为

suspend/resume,不推荐使用,因为有两个缺点,一个是不释放锁,第二个是要严格按照加锁解锁的顺序进行,不然会出现死锁现象

 不释放锁,指的是当两个线程都在同个对象锁的同步代码块中分别执行了suspend和resume,那么当suspend挂起时不会释放同步代码块的对象锁,而当第二个线程要进入同个对象锁的同步代码块执行resume时,由于对象锁没有释放,导致无法进入同步代码块唤醒线程,从而两个线程都挂起,造成死锁

  顺序问题导致的死锁指的是当resume提前调用,而suspend后面调用的话,会导致suspend线程一直等待而到死锁

wait/notify

  解决了不释放锁的问题,因为执行wait的时候会释放锁,所以就不存在上文的同一个对象锁下的代码块无法都执行到。

但是依然存在顺序问题导致的死锁,也是因为notify后执行wait,导致wait线程一直挂起,造成死锁

synchronized(ObjectA){
  while(不满足条件){
    ObjectA.wait();
    }   
    //执行逻辑todo 
}

synchronized(ObjectA){
    //执行逻辑 todo
    ObjectA.notifyAll();
}

park/unpark

   解决了顺序问题,因为park/unpark机制是通过发放令牌的机制,也就是说当执行unpark的时候会发放一块令牌,就算unpark先执行,park后执行,也会因为unpark线程已经发放了令牌,而park的时候拿到unpark先前发放的令牌而直接通过执行

但是因为不会释放锁,所以依然存在不释放锁导致的死锁问题.

顺带说一下伪唤醒的概念,存在一种情况就是,当wait/suspend/park 将线程挂起的时候,会存在没有执行notify/resume/unpark ,但是挂起线程依旧醒来继续执行的情况,为了防止这种情况造成的代码逻辑不合原意的情况,我们在判断是否进入等待状态的代码应该使用循环的方式来判断,这样子就可以在线程醒来的情况下再判断一下是否满足醒来的条件从而避免伪唤醒的情况.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值