java中synchronized用法
源地址:http://blog.csdn.net/chenguang79/article/details/677720
作者: chenguang79
之前一直困惑于 synchronized(){} 语句块的问题 。()内到底是传什么?synchronized锁什么? 看了这篇文章,也有了一点清晰吧!单直到看到这篇文章的以下评论,问题就来了!!!
我自己也去试了下,可以得到的结果就是 此时是同步了的。但我上面的两个问题又晕了
所以我纠结呀。就又有了以下小结吧!!
synchronized(){} 语句块中
1.()传的是你要锁的对象也可以,类模板也行!
2.但最终比较的是:如果是传对象就得两个对象相同时锁,或者传类模板(类模板必须是类名.class 才会判别成功 如果的对象.getClass() 就还是会判别为该对象而不是类模板)则是该类全部都
例:代码1 时没有锁住 即 obj obj.getClass 和新对象 新对象.getClass() 都不能锁住
代码1:
private static int num=0;//用于判断是否锁住之一
public static void Learing(Object obj,String a){
synchronized (obj.getClass()) {
System.out.println(obj.getClass());
num++;
System.out.println(a+":开始上课"+num);
}
}
public static void main(String[] args) {
Theacher t=new Theacher();
Students s=new Students();
t.start();
s.start();
}
}
public void run() {
NewTest.Learing(this,"学生");
}
}
public void run() {
NewTest.Learing(this,"老师");
}
}
锁住的情况:即为 Object.class Students(Teacher).class
还有一种对象实例方法直接传 “ this ” 肯定能锁就没又试了。
直到我准备上传时,又一个问题来了!以上代码中传入NewTest.class new NewTest().getClass() 时会锁住!!! new NewTest()时不会锁住!!!
代码2:
public class NewTest {
public static void main(String[] args) {
Theacher t=new Theacher();
Theacher t0=new Theacher();
Students s=new Students();
t.start();
t0.start();
s.start();
}
}
class NewTest1{
private static int num=0;
public static void Learing(Object obj,String a){
synchronized (new NewTest().getClass()) {
System.out.println(obj.getClass());
num++;
System.out.println(a+":开始上课"+num);
}
}
}
换成这个代码也是一样的。按道理应该都不会锁住的呀!!
3.将synchronized作用于static函数,示例代码如下:
示例:
Class Foo
{
public synchronized static void methodAAA() //同步的static函数
{
//….
}
public void methodBBB()
{
synchronized(Foo.class) // class literal(类名称字面常量)
}
}
代码中的methodBBB()方法是把class literal作为锁的情况,它和同步的static函数产生的效果是一样的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。
这是源文章,我还是之前没读懂呀!意思两个方法是同一个效果,静态方法默认会锁该方法所在类的 类模板 。
最后得出:
* 静态synchronized (){}中貌似可以放任何 在内存中有地址的数据(对象,
* 类模版,数组,枚举都可以) 但不能为空
* 而且都是启动了 同步锁 语句块,问题是是否是同一个同步锁。
* ()内传入了一个已经存在的内存地址并且不会改变时,就会把该语句块看作
* 时同一把锁,这也说明如果是新创建了一个对象(new关键字时)时 ,产生了两
* 个新对象,新地址,不会达到同步锁的效果,所以新对象.getClass()也是一样的,
* 新创了两个对象,地址不同了,虽然类模版是同一个。
* 如果在语句块中改变了()内的数据,这个锁可能就不会达到效果,也就反面验证以上结论!
* 类似于synchronized是一个门,()是一个门卫,一个线程进去后如果门卫就换了,
* 新门卫肯定不认识后面的线程,就会让它进去!(之前理解错了,以为是类似对象比较)
* 而非静态synchronized (){}中相较于以上就多一个this 当该语句块没结束
* 时this一直不会改变,所以只要不是新对象调用就不会出现没同意锁的问题