java高并发多线程架构_《Java高并发编程详解-多线程架构与设计》线程间的通信...

同步、异步、阻塞、非阻塞概念

同步和异步

结果的通知机制。自己问还是别人通知。

同步:主动等待结果的返回。如阻塞等待,轮询(同步非阻塞)。

异步:被动等待结果的返回。如 消息回调。

阻塞和非阻塞

结果返回以前,调用方的状态。等还是不等。

阻塞:结果返回以前,什么也不干。

非阻塞:在结果返回以前,可以先做一些其他事情。

Monitor锁

下面所说的获取monitor锁都是指的先使用synchronized获取对象锁

不应该叫synchronized(mutex)为锁,而应该是某个线程获取了与mutex关联的monitor锁。

wait 与 notify

wait 理解成线程在等待直到该对象可用。(被notify后就不再等待)

notify理解成线程通知该对象可用。

使用wait的注意事项

wait必须在同步方法中使用,因为wait必须由拥有monitor(已用synchronize获取锁)的线程调用。

wait可以被中断,为了防止wait被interrupt唤醒,wait方法需要在循环中使用。

使用wait后自动释放线程对应的锁。–release ownership of this monitor

wait会等待直到其他线程调用notify/notifyAll唤醒。–waits until anthoer thread notifies threads waiting on this object’s monitor to wake up…

被notify/notifyAll唤醒后会重新获得锁的拥有权,然后接着执行。–re-obtain ownership of the monitor and resumes execution.

线程调用wait后, 会加入与之对应的wait set.每个对象都有一个与之对应的wait set.使用notify会将其中一个弹出,notifyAll弹出所有线程。(C5.3.2)

Causes the current thread to wait until another thread invokes the

* {@link java.lang.Object#notify()} method or the

* {@link java.lang.Object#notifyAll()} method for this object.

* In other words, this method behaves exactly as if it simply

* performs the call {@code wait(0)}.

*

* The current thread must own this object’s monitor. The thread

* releases ownership of this monitor and waits until another thread

* notifies threads waiting on this object’s monitor to wake up

* either through a call to the {@code notify} method or the

* {@code notifyAll} method. The thread then waits until it can

* re-obtain ownership of the monitor and resumes execution.

* As in the one argument version, interrupts and spurious wakeups are

* possible, and this method should always be used in a loop:

* synchronized (obj) {

* while ()

* obj.wait();

* … // Perform action appropriate to condition

* }

* This method should only be called by a thread that is the owner

* of this object’s monitor. See the {@code notify} method for a

* description of the ways in which a thread can become the owner of a monitor.

使用notify的注意

必须在同步方法中使用wait、notify,因为他们的使用前提都是持有monitor所有权。

同步代码块的monitor必须与执行 wait 、notify的对象一致,也就是说对哪个对象同步,才能调用那个对象的 wait、notify。

例子:

若不是用的notifyAll, 则不能用于多线程环境

3eb28bd50645751cb996c1a01f00610a.png

5636907fd7ca50c3cea06d8d2cb0a4b0.png

在while而不是if中调用wait!否则一旦被interrupt,会跳过判断继续执行。如

d9127a779f3069d318cd7cd4c9384935.png

测试主动interrupt对if中使用wait的影响

这里主动interrupt,可见当producer被interrupt后,producer就略过了判断,继续添加了一个event

e74a65828a77e1ee97705287033a44d8.png

wait与sleep的

相同:

使线程阻塞

可以中断

不同:

wait是Object的方法,sleep是Thread的

wait必须要在同步代码块中执行。

wait会释放monitor的锁,sleep不会

sleep短暂休眠后会退出阻塞?(TODO)wait(没有指定时间的话)必须被中断才会退出阻塞。

synchronized的缺点

无法中断

synchronized不像sleep和wait那样,可以被中断。

没有等待时间

其他线程获取锁的拥有权必须要等待锁的拥有者(线程)释放后才能执行。

利用wait、notify实现可中断的BooleanLock

p96-104

一旦从wait中被唤醒则有机会检查lock是否为false,为false则修改获取锁的线程cureentLockThread为自己,并设置lock为true.防止其他线程继续争抢。

如果wait超时会报错,notify后超时 也主动抛错。

关键代码

b3c7a59902174795cf8492b683a3369a.png

从wait中被notify或者等待超时后,会因为while(locked),locked为false,说明没有线程持有monitor的拥有权,因此跳出while设置locked=true;this.currentThread=currentThread();

c36008a38b6c03b878e191fa4054cdd8.png

优化,超时后清除blackList

abb8e5cedb7a3587aa72b51d50c2bb90.png

发布于2019年7月7日 16:40:43

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值