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