1.概括
应该理解的是:锁是用来限制对资源的使用的。当需要使用锁的时候,有两个方面是需要考虑的:
- 1.用什么对象作为锁?
- 2.锁住的是什么内容?
2.用什么对象作为锁?
举一个不免俗套但是很形象的例子:排队上厕所。当一个人进入厕所之后,他需要给厕所加把锁,以表明厕所现在为我所有,你们就不要挣了,这把锁必须是有威严的锁,比如公家的锁,不然别人不认。你要所拿一把自己家的锁,那就相当于私锁了,别人还是会破门而入的,因为别人不认识这把锁。当然,如果遇到熟人,他认这把锁,他还是会乖乖排队的,规范一点讲,什么时候别人会认这把锁呢?----当他手里的锁跟正锁在门上的锁一致时,他就认。
在java中也是一样的,你需要一段代码(资源)在什么层次上互斥,那就给他加什么层次的锁,比如:
synchronized (this){//在this对象的层次上是互斥的,每一条携带this来的线程都会等待
---
}
synchronized (Obj obj){//在obj对象的层次上是互斥的,每一条携带obj来的线程都会等待
---
}
看下面的例子:
new Thread() {
@Override
public void run() {
super.run();
show(new String());
}
}.start();
new Thread() {
@Override
public void run() {
super.run();
show(gnew String());
}
}.start();
public void show(String lock) {
synchronized (lock) {
------
}
}
show方法中的代码是不会互斥的,因为访问他的两条线程带来了不同的锁。只有他们使用唯一的锁,资源才会被竞争。
3.锁住的是什么内容?
常见的锁住的内容有两种:
- 代码块:
synchronized (Obj obj){
---
}
- 方法:默认的锁就是方法所在的对象
public synchronized void function() {
-----
}
值得注意的是:静态方法的对象锁类对象,在整个程序中时唯一的。
public static synchronized void function() {
-----
}