Java monitor

来源:互联网 发布:网络播音设备 编辑:程序博客网 时间:2024/05/16 05:06

在Java中使用线程同步来解决线程竞争的问题。但是有些方法使用还是需要有些注意点,这里我们主要来谈一下Object 类中的wait和notify/notifyAll 方法。

首先这两个方法使用范围:

wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用 (而Thread中的sleep可以在任何地方使用)
synchronized(x){  x.notify()  //或者wait()  }

当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。
当执行notify/notifyAll方法时,会唤醒一个处于等待该 对象锁 的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。

故,在实际编程中,我们应该尽量在线程调用notify/notifyAll()后,立即退出临界区。即不要在notify/notifyAll()后面再写一些耗时的代码。

如:

synchronized (this) {    while (true) {    notify();    }}

这里就是做了锁粗化的结果,但是同步块中是一个死循环,所以这样的粗化后的结果就是该代码就会一直占用对象锁,即使notify也无效,在这里我们只能通过减少锁持有时间来使锁对象内部代码尽量占用最少的时间,来减小锁竞争的产生的耗时。

即原则是如果同步代码块内部执行的不是很多的代码块,那么就使用锁粗化,但是如果内部执行很耗时的代码,那么这里只能通过减少持有锁的时间来减少锁竞争的时间损耗。

还有该线程interrupt()时,处于wait中的线程“立即”被唤醒(一般是立即响应中断请求),并抛出异常。此时,线程也就结束了。

0 0
原创粉丝点击