Thursday, July 10, 2014

Java 多线程 - Synchronized 和 Lock

一个process里面所有的threads是共享同一块memory space的, 所以有时候就需要去避免两个threads同时修改一块resource所引起的问题。 Java里引入Synchronized 和 Lock的概念。

1), synchronized method
class Myobject{
  public synchronized void foo(String name){
   .......................................
  } 
}
synchronized 关键字限制的是Myobject这个类的一个对象的多个threads不能访问同一个资源,不同对象的线程是可以同时访问的。

2), 一个class多个synchronized 方法:
class Myobject{
  public synchronized void bar(String name){
   。。。。。。。。。
  }
  public synchronized void foo(String name){
   。。。。。。。。。
  } 
}
Java的每个对象都有一个锁(lock或monitor), 当一个thread访问synchronized方法时, 该对象就被锁住了, 在解锁(执行完毕或抛出异常)之前, 该对象的任何thread都不能再访问其他的synchronized的方法。注意:是对象被上锁,而不是一个synchronized方法一个锁。

3), Synchronized 和 Static Synchronized
class Myobject{
   public static synchronized void bar(String name){
    。。。。。。。。。
   } 
}
静态变量时属于class的,不是属于对象的, 若一个thread访问static synchronized 方法时, 则这个class被上锁,在解锁之前,这个class的所有对象的所有thread都不能访问该方法和其他synchronized的方法。

4), Synchronized Block
class Myobject{
  public void foo(String name){
    synchronized(this){
     。。。。。。。。。
    }
  } 
}
class Myobject{
  private AnotherClass object = new AnotherClass();
  public void foo(String name){
    synchronized(object){
     。。。。。。。。。
    }
  } 
}
Block用来同步一段代码, 和synchronized method一样,对于每个对象,它只有一个thread可以访问Synchronized block里面的东西。注意synchronized里面的object可以是任意类的object

5), Locks
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Myobject {
  private Lock lock;
  public Myobject(){
    lock = new ReentrantLock();
  }

  public void foo(){
    lock.lock();
      ........
    lock.unlock();
 }
}

和synchronized类似,一个对象在某一个时间只能有一个thread holds the lock。 避免了lock之间的资源被其他thread随意修改。 比较典型的例子是ATM取款存款机。

No comments:

Post a Comment