Java的synchronized加在方法上或者对象上有什么区别?
2014-02-26 12:35
507 查看
Java的synchronized加在方法上或者对象上有什么区别?
Java的synchronized可以加在方法上,也可以直接加在对象上,从而保证一段代码只能有一个线程在运行,保证线程的同步。那么这两者究竟有啥区别呢?我们可以看下面的示例代码。
view
source
print?
001 | public class SyncTest { |
002 |
003 | public static synchronized void testSyncOnStaticMethod() { |
004 | System.out.println( "testSyncOnStaticMethod" ); |
005 | try { |
006 | Thread.sleep( 10000 ); |
007 | } catch (InterruptedException e) { |
008 | } |
009 | } |
010 |
011 | public static void testSyncOnClass() { |
012 | synchronized (SyncTest. class ) { |
013 | System.out.println( "testSyncOnClass" ); |
014 | try { |
015 | Thread.sleep( 10000 ); |
016 | } catch (InterruptedException e) { |
017 | } |
018 | } |
019 | } |
020 |
021 | public synchronized void testSyncOnMethod() { |
022 | System.out.println( "testSyncOnMethod" ); |
023 | try { |
024 | Thread.sleep( 10000 ); |
025 | } catch (InterruptedException e) { |
026 | } |
027 | } |
028 |
029 | public void testSyncOnThis() { |
030 | synchronized ( this ) { |
031 | System.out.println( "testSyncOnThis" ); |
032 | try { |
033 | Thread.sleep( 10000 ); |
034 | } catch (InterruptedException e) { |
035 | } |
036 | } |
037 | } |
038 |
039 | public static void case1() { |
040 | // case1 |
041 | // 先输出testSyncOnThis或者testSyncOnMethod |
042 | // 然后停顿10秒,再输出另一个 |
043 | // 这个现象表明了 |
044 |
045 | // public synchronized void func() { |
046 | // } |
047 |
048 | // 等价于 |
049 |
050 | // public void func() { |
051 | // synchronized (this) { |
052 | // } |
053 | // } |
054 | final SyncTest t1 = new SyncTest(); |
055 | new Thread( new Runnable() { |
056 |
057 | @Override |
058 | public void run() { |
059 | t1.testSyncOnThis(); |
060 | } |
061 | }).start(); |
062 |
063 | new Thread( new Runnable() { |
064 |
065 | @Override |
066 | public void run() { |
067 | t1.testSyncOnMethod(); |
068 | } |
069 | }).start(); |
070 | } |
071 |
072 | public static void case2() { |
073 | // case2 |
074 | // 先输出testSyncOnClass或者testSyncOnStaticMethod |
075 | // 然后停顿10秒,再输出另一个 |
076 | // 这个现象表明了 |
077 |
078 | // public synchronized static void staticFunc() { |
079 | // } |
080 |
081 | // 等价于 |
082 |
083 | // public static void staticFunc() { |
084 | // synchronized (SyncTest.class) { |
085 | // } |
086 | // } |
087 | new Thread( new Runnable() { |
088 |
089 | @Override |
090 | public void run() { |
091 | SyncTest.testSyncOnClass(); |
092 | } |
093 | }).start(); |
094 |
095 | new Thread( new Runnable() { |
096 |
097 | @Override |
098 | public void run() { |
099 | SyncTest.testSyncOnStaticMethod(); |
100 | } |
101 | }).start(); |
102 | } |
103 |
104 | public static void main(String[] args) { |
105 | case1(); |
106 | case2(); |
107 | } |
108 | } |
如果synchronized加在一个类的普通方法上,那么相当于synchronized(this)。
如果synchronized加载一个类的静态方法上,那么相当于synchronized(Class对象)。
在使用多线程的时候,知道这个是很关键的,因为synchronized的两种不用用法可能导致两段不相干的代码是互斥的,增加了同步的开销(例如这里的函数testSyncOnThis和testSyncOnMethod,他们在同一个对象this上加了锁),更严重的是可能导致死锁。
注:如果要试验,上面的case1和case2请分开运行(可以跑两次,每次注释掉其中一个语句),这样子可以看得比较清楚。
转自 http://blog.iamzsx.me/show.html?id=126001
相关文章推荐
- Java的synchronized加在方法上或者对象上有什么区别?
- java中synchronized的普通方法与静态方法获取的锁对象是什么
- java synchronized对象锁与类锁的区别、同步代码块与同步方法的区别
- java多线程-synchronized对象和方法的区别
- JAVA中创建一个对象有哪几种方法,有什么区别?
- Java synchronized 对象锁与类锁的区别、同步代码块与同步方法的区别 详解
- java synchronized 方法 对象 区别
- Java Synchronized获得类的锁和获得对象的锁有什么区别呢?
- Java - Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?
- Java synchronized 对象锁与类锁的区别、同步代码块与同步方法的区别 详解
- Java_类和对象(完美总结)_转载_覆盖和隐藏的区别,覆盖就不能使用了,而隐藏提供全局方法名或者全局变量名还可以使用
- Java中的构造方法与普通方法的区别? 什么情况下用构造方法什么情况下用普通的方法
- ”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
- synchronized修饰方法和对象的区别
- 什么叫运行时才确定调用那个(对象或者方法)?
- java中new一个对象和对象=null有什么区别
- java synchronized关键字的用法以及锁的等级:方法锁、对象锁、类锁
- java中Integer对象不同创建方法之间的区别
- 深入理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
- java 中的 wait()方法和 sleep()方法的区别是什么?