码迷,mamicode.com
首页 > 其他好文 > 详细

怎样在静态方法中使用synchronized

时间:2014-10-16 04:46:02      阅读:405      评论:0      收藏:0      [点我收藏+]

标签:synchronized

synchronized的实现方式


synchronized的类型可以分为两种:

  1. synchronized method
  2. synchronized block

两者的实现方式是不一样的,jvm规范中写道,编译后的synchronized method 会有一个 ACC_STATIC 的flag,也就是说当jvm的方法调用指令(the method invocation instruction)从the run-time contant pool 中查找到这个method的时候,已经知道它是一个synchronized method,所以锁操作是由方法调用以及返回指令来控制的。
而 synchronized block 的锁是由 monitorentermonitorexit 这两个指令来控制。


可以通过 javap 命令来“反汇编”一下class文件。


java代码:

public class StaticMethodTest {
    public static synchronized void staticMethod() { }
    public static void staticMethod1() {
        synchronized (StaticMethodTest.class) {
        // ...
    }
    }
    public void memberMethod() { } 
}


编译成class文件后执行

javap -verbose StaticMethodTest


两个静态方法的输出结果分别为

public static synchronized void staticMethod();
  descriptor: ()V
  flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
  Code:
    stack=0, locals=0, args_size=0
       0: return
    LineNumberTable:
      line 2: 0
public static void staticMethod1();
  descriptor: ()V
  flags: ACC_PUBLIC, ACC_STATIC
  Code:
    stack=2, locals=2, args_size=0
       0: ldc           #2                  // class StaticMethodTest
       2: dup
       3: astore_0
       4: monitorenter
       5: aload_0
       6: monitorexit
       7: goto          15
      10: astore_1
      11: aload_0
      12: monitorexit
      13: aload_1
      14: athrow
      15: return
    Exception table:
       from    to  target type
           5     7    10   any
          10    13    10   any


其实不管静态方法还是成员方法,synchronized的实现方式都是一样的,那么类和对象究竟有什么关系呢?


类和对象


首先要了解的就是类究竟是怎么来的。 


JVM拿到编译器编译好的class文件后,首先会把文件载入到内存中,class文件当然会有自己的格式,所以需要由ClassLoader来解析文件的内容,这个解析出来的内容会用一个Class类的实例 - Class object 来表示,这个object可以通过Java的

ClassName.class

来获取。


也就是说,Class object 是一个Class类型的实例(instance),而对象是一个ClassName的instance。Class 和 ClassName都是类型,ClassName是由class关键字定义的,而Class是内置类型。


因此成员方法的synchronized method 就等价于 synchronized (this) block,即下面两种方式是等价的。

public synchronized void fun1() {
    // do something here
}


public synchronized void fun2() {
    synchronized (this) {
    // do something here
    }
}

成员方法是属于this,而静态方法是属于Class Object,那么静态方法的 synchronized method也就等价于下面这种形式的 synchronized block 了。

public static synchronized void fun2() {
    synchronized (ClassName.class) {
    // do something here
    }
}

验证代码


定义了三个静态方法,分别采用不同的锁机制,并且每个方法都是一个死循环。然后再定义三个线程分别执行调用三个方法。

import java.util.concurrent.*;


public class SynchronizedTest {


    private static Object lock = new Object();


    public synchronized static void fun() {
        while (true) {
            System.out.println("in fun");
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    }


    public static void fun1() {
        synchronized (SynchronizedTest.class) {
            while (true) {
                System.out.println("in fun1");
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                    e.printStackTrace();
            }
            }
        }
    }


    public static void fun2() {
        synchronized (lock) {
            while (true) {
                System.out.println("in fun2");
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                    e.printStackTrace();
            }
            }
    }
    }


    public static void main(String[] args) {
        new Thread() {
        @Override
        public void run() {
            fun();
        }
    }.start();


        new Thread() {
        @Override
        public void run() {
            fun1();
        }
    }.start();


        new Thread() {
        @Override
        public void run() {
            fun2();
        }
    }.start();
    }
}

运行结果就是 in funin fun2 交替出现,就是没有 in fun1
只要运行fun的线程不交出锁,fun1就无法被方法,因为他们都是共享了 Class object 的锁。

怎样在静态方法中使用synchronized

标签:synchronized

原文地址:http://blog.csdn.net/feelang/article/details/40134631

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!