synchronized,理解再深入那么一点
class Object{
element;
public synchronized void method(){}
}
【描述】线程1,对synchronized(element)访问,线程2,对synchronized A()方法进行访问。
【结论】获取成员变量的锁,与获取对象的锁,是独立的。并不存在说,要获取对象的锁,就要求成员变量或神马的都没有锁存在了。即,锁成员变量与锁整个对象是独立的。
【描述】在前面描述的基础上,如果method()方法内部,又需要对element()同步访问。
【结论】那就得等了,等先前对element的锁释放。
class Object extends Thread{
public synchronized void fun(){}
public synchronized void run(){}
}
【描述】run()的时候,可以调用对象内synchronized B(),因为反正其已获取到对象锁。但如果另外一个线程,已获取对象锁,在访问fun(),那么run()就必须得等了。
【结论】给run()前加synchronized需谨慎,可能造成的影响有:1. 如果run()一早获取对象锁,那么它跑起来,别人都别想访问这里的同步方法了,例如fun();2. 如果run()一早没有获取对象锁,那么它跑不起来,必须得等别人释放了对象的锁,如fun()执行结束,该线程才可以跑起来。
class Object{
public static synchronized void mm(){}
}
【描述】synchronized除了用于对象、成员变量,还可用于锁“类”。
【备注】
1. 被synchronized声明的方法被称为同步方法,被其修饰的代码块称为同步语句。无论是同步方法还是同步语句,只要声明为同步了,在同一时刻,同一个对象的同步XX是不可以被同时访问的,而不同对象之间的同步方法是互不干扰的。
2.
private byte[] lock= new byte[0];
Public void change() {
Synchronized(lock) {
}
}
自定义锁注意事项:
a)必须是private,防止在类外部引用改变。
b)如果可能用到,重写get方法,返回对象的clone,而不是本身。
3.
Class Foo {
public synchronizedstatic void methodAAA()// 同步的static 函数
{
//….
}
public void methodBBB() {
synchronized(Foo.class)// class literal(类名称字面常量) 同一时刻,被修饰部分只有一个对象可以运行,因为它的声明是针对类的。
} }