首页 > 代码库 > 有关synchronized同步笔记

有关synchronized同步笔记

synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

注意:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。


1.对象实例的锁

class Test{

    public synchronized void f1(){

    //do something here

    }

    public void f2(){

    synchronized(this){

    //do something here

    }

    }

    }

上面的f1()和f2()效果一致, synchronized取得的锁都是Test某个实列(this)的锁.比如: Test t = new Test();线程A调用t.f2()时, 线程B无法进入t.f1(),直到t.f2()结束.

 作用:多线程中访问Test的同一个实例的同步方法时会进行同步.


2.class的锁

class Test{

    final static Object o= new Object();

    public static synchronized void f1(){

    //do something here

    }

    public static void f2(){

    synchronized(Test.class){

    //do something here

    }

    }

    public static void f3(){

    try {

    synchronized (Class.forName("Test")) {

    //do something here

    }

    }

    catch (ClassNotFoundException ex) {

    }

    }

    public static void g(){

    synchronized(o){

    //do something here

    }

    }

    }

上面f1(),f2(),f3(),g()效果一致

   f1(),f2(),f3()中synchronized取得的锁都是Test.class的锁.

   g()是自己产生一个对象o,利用o的锁做同步

    作用:多线程中访问此类或此类任一个实例的同步方法时都会同步. singleton模式lazily initializing属于此类.


3.static method

class Test{

    private static int v = 0;

    public static void f1(){

    //do something, 但函数中没用用到v

    }

    public synchronized static void f2(){

    //do something, 函数中对v进行了读/写.

    }

    }

多线程中使用Test的某个实列时,

    (1)f1()是线程安全的,不需要同步

    (2)f2()这个静态方法中使用了函数外静态变量,所以需要同步.



有关synchronized同步笔记