java 多线程 synchronized与Object类中wait、notify、notifyAll方法的使用

synchronized的使用:

(1)synchronized(obj){}的使用

obj是一个实例对象,可以是任意对象,当在多线程中通过各种方式执行到该synchronized包围的代码段,需要先拿到obj对象的锁才能继续往后执行,否则就阻塞,阻塞的时候一直判断有没有拿到obj的锁,如果拿到obj的锁了,就可以继续执行,如果还没拿到obj的锁,继续阻塞。

(2)synchronized用在实例方法(或者叫做动态方法)上

相当于(1)中所说的

synchronized(this){

     //实例方法的代码放在这...

}

(3)synchronized用在静态方法上

假设该静态方法属于A类,则相当于(1)中所说的

synchronized(A.class){

     静态方法的代码放在这...

}

Object中wait、notify、notifyAll方法的使用

正常使用这三个方法的前提:这三个方法的使用必须在同步代码块中,并且该同步代码块拿到的锁必须是这个几个方法所属对象的锁。否则报异常。

1、wait的使用

   假设wait()属于对象a,当在线程中调用a.wait()时,则该线程会释放锁,然后被阻塞,再放到对象a的线程等待集中。。直到被唤醒才能转为可运行状态去争夺锁。唤醒可用对象a的notify和notifyAll方法,每个对象的这两个方法只能唤醒所属对象对应等待集中的线程。

所以,当在线程中直接调用wait方法时,与this.wait()是等价的。这个时候就要注意wait所属对象是哪个了,如果所属对象找错了,那就一直不能唤醒该对象的等待集了。

直接调用wait()方法的使用常发生在实例方法上使用synchronized,所以,尽量使用synchronized(obj){}这种形式。

2.notify的使用

唤醒该notify()方法所属对象的等待集中随机一个线程,被唤醒的线程处于可运行状态,即可以争夺对象锁的状态,只要争夺到锁,该线程就可以继续执行了。

3.notifyAll的使用

唤醒该notifyAll()方法所属对象的等待集中所有线程,被唤醒的线程处于可运行状态,即可以争夺对象锁的状态,只要争夺到锁,该线程就可以继续执行了。


猜你喜欢

转载自blog.csdn.net/qq_36951116/article/details/81014267
今日推荐