浅谈在多线程编程中,synchronized关键字同步作用于对象,而非作用于代码

类别:Java 点击:0 评论:0 推荐:

关键字synchronized可以作为JAVA方法修饰符,也可以作为JAVA方法内的语句。
被它修饰的代码部分往往被描述为临界区。这使很多人认为,由于代码被syscharonized保护着,
因此同一时刻只能有一个线程访问它。

对于JAVA类中的方法,关键字sysnchronized其实并不锁定该方法或该方法的部分代码,它只是锁定对象。

当synchronized被当做方法修饰符的时候,他所取得的lock将被交给方法调用者(某对象)。如果synchronized作用于某对象的引用,则取得的lock将交给该引用所指的对象。例如:


class Test{
public synchronized void method1()  //注释:修饰方法
{
// .......    
}

public void method2()              
{
  synchronized(this){                   //注释:修饰对象的引用
// .....
 }
}

public void method3(SomeObject someObj)
{
synchronized (someObj){                   //注释:修饰对象的引用
//...
}
}
}

对一个对象进行同步控制到底意味什么呢?它说明调用该方法的线程将会取得对象的lock。持有对象A的lock的线程,如果另外通过synchronized函数或者synchronized语句来申请对象A的lock的线程,在该lock被释放前无法获得满足。
因此,synchronized方法或synchronized区段内的代码在同一时刻下可有多个线程执行,只要是对不同的对象调用该方法。例如下代码:
class Foo extends Thread
{
 private int val;
 public Foo(int v)
 {
  val=v;
 }
 public synchronized void printVal(int v)
 {
  while(true)
   System.out.println(v);
 }
  public void run()
  {
 printVal(val);
  }
}

class Bar extends Thread
{
 private Foo sameFoo;
 public Bar(Foo f)
{
  sameFoo=f;
}

public void run()
{
 sameFoo.printVal(2);
}
}
class Test
{
 public static void main(String args[])
 {
  Foo f1=new Foo(1);
  f1.start();
  Bar b=new Bar(f1);
  b.start();
  Foo f2=new Foo(3);
  f2.start();
 }
}
结果:
1
1
1
1
3
3
3
3
1
1
1
3
3
3

本文地址:http://com.8s8s.com/it/it15883.htm