synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
在进一步阐述之前,我们需要明确几点:
A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)与之相关联。
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都可以调用它们。
{
public synchronized void AAA()
{
System.out.println("aaa begin");
try{Thread.sleep(5000);}
catch(Exception ex){}
System.out.println("this is method aaa");
System.out.println("aaa end");
System.out.println("--------------------------------");
}
public synchronized void BBB()
{
System.out.println("bbb begin");
try{Thread.sleep(5000);}
catch(Exception ex){}
System.out.println("this is method bbb");
System.out.println("bbb end");
System.out.println("--------------------------------");
}
public synchronized void DDD()
{
System.out.println("ddd begin");
try{Thread.sleep(5000);}
catch(Exception ex){}
System.out.println("this is method ddd");
System.out.println("ddd end");
System.out.println("--------------------------------");
}
public void CCC()
{
System.out.println("ccc begin");
System.out.println("this is method ccc");
System.out.println("ccc end");
System.out.println("--------------------------------");
}
synchronized static void method(){
System.out.println("static begin");
try{Thread.sleep(2000);}
catch(Exception ex){}
System.out.println("static end");
}
}
{
private MySync ms = null;
private String ty = null;
public MySync getMs()
{
return ms;
}
public void setMs(MySync ms)
{
this.ms = ms;
}
public String getTy()
{
return ty;
}
public void setTy(String ty)
{
this.ty = ty;
}
public void run()
{
if(ty.equals("a"))
ms.AAA();
else if(ty.equals("b"))
ms.BBB();
else if(ty.equals("c"))
ms.CCC();
else if(ty.equals("d"))
ms.DDD();
}
}
为了说明将test类的main方法单独说明
此main方法可以演示同一类的同一实例在不同线程中的synchronized 效果是互斥的
public static void main(String [] args)
{
MySync m = new MySync();
Test t = new Test();
t.setMs(m);
t.setTy("a");
t.start();
MySync m1 = new MySync();
t = new Test();
t.setMs(m1);
t.setTy("a");
t.start();
}
此main方法可以演示同一类的不同实例在不同线程中的synchronized 效果是不互斥的
有此说明当一个对象m在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象m1却可以任意调用这个被加了synchronized关键字的方法。
以上说的是方法级的synchronized;
{
MySync m = new MySync();
Test t = new Test();
t.setMs(m);
t.setTy("a");
t.start();
t = new Test();
t.setMs(m);
t.setTy("a");
t.start();
}