Java的类锁和对象锁
2015-12-18 09:16
218 查看
类锁和对象锁不是同1个东西,一个是类的Class(对应的唯一的一个即这类的二进制字节码)对象的锁,1个是类的实例(!即new出的一个类的对象,一个类会有多个实例对象)的锁。也就是说:1个线程访问静态synchronized的时候,允许另一个线程访问对象的实例synchronized方法。反过来也是成立的,因为他们需要的锁是不同的。
对象锁:java的所有对象(即new出的一个类的对象,一个类会有多个实例对象)都含有1个互斥锁,这个锁由JVM自动获取和释放。线程进入synchronized方法的时候获取该对象的锁,当然如果已经有线程获取了这个对象的锁,那么当前线程会等待;synchronized方法正常返回或者抛异常而终止,JVM会自动释放对象锁。这里也体现了用synchronized来加锁的1个好处,方法抛异常的时候,锁仍然可以由JVM来自动释放。
类锁:对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。我们都知道,java类可能会有很多个对象,但是只有1个Class对象,也就是说类的不同实例之间共享该类的Class对象。Class对象其实也仅仅是1个java对象,只不过有点特殊而已。由于每个java对象都有1个互斥锁,而类的静态方法是需要Class对象。所以所谓的类锁,不过是Class对象的锁而已。获取类的Class对象有好几种,最简单的就是MyClass.class的方式。
对象锁和类锁的测试
可以看出,类锁和对象锁不是同1个东西,一个是类的Class对象的锁,1个是类的实例的锁。也就是说:1个线程访问静态synchronized的时候,允许另一个线程访问对象的实例synchronized方法。反过来也是成立的,因为他们需要的锁是不同的。
对象锁:java的所有对象(即new出的一个类的对象,一个类会有多个实例对象)都含有1个互斥锁,这个锁由JVM自动获取和释放。线程进入synchronized方法的时候获取该对象的锁,当然如果已经有线程获取了这个对象的锁,那么当前线程会等待;synchronized方法正常返回或者抛异常而终止,JVM会自动释放对象锁。这里也体现了用synchronized来加锁的1个好处,方法抛异常的时候,锁仍然可以由JVM来自动释放。
类锁:对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。我们都知道,java类可能会有很多个对象,但是只有1个Class对象,也就是说类的不同实例之间共享该类的Class对象。Class对象其实也仅仅是1个java对象,只不过有点特殊而已。由于每个java对象都有1个互斥锁,而类的静态方法是需要Class对象。所以所谓的类锁,不过是Class对象的锁而已。获取类的Class对象有好几种,最简单的就是MyClass.class的方式。
/** * */ /** * 对象锁和类锁的使用 * <p>Title: MyTest</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 杰 * @date 2015年12月17日 下午10:45:15 * @vesion 1.0 */ public class MyLock { /** * 对象锁:形式1 * synchroined 修饰方法 直接方法名,对应的是当前类的new出来对象实例的实例硕 */ public synchronized void objLockMethod1() { System.out.println("in...objLockMethod1"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("out...objLockMethod1"); } /** * 对象锁:形式2 * synchonced(this) 修饰代码块 ,this代表的是当前类的实例对象锁 */ public void objLockMethod2() { synchronized (this) { System.out.println("in...objLockMethod2"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("out...objLockMethod2"); } } /** * 类锁:形式1 * static 类 用synchronized修饰 对应的是该类对应的Class类对象,只有唯一的一个 */ public static synchronized void classLock1() { System.out.println("classLock1------in"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("classLock1------out"); } /** * 类锁:形式2 * synchronized (MyLock.class) * synchronized中的锁使用 本类名.class 对应的是该类对应的Class类对象,只有唯一的一个 */ public static void classLock2() { synchronized (MyTest.class) { System.out.println("classLock2------in"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("classLock2------out"); } } }
对象锁和类锁的测试
/** * */ /** * <p>Title: Thread1</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 杰 * @date 2015年12月17日 下午11:20:40 * @vesion 1.0 */ public class Thread1 implements Runnable{ MyLock myLock ; public Thread1(MyLock myLock) { this.myLock = myLock; } @Override public void run() { myLock.classLock1(); } }
/** * */ /** * <p>Title: Thread1</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 杰 * @date 2015年12月17日 下午11:20:40 * @vesion 1.0 */ public class Thread2 implements Runnable{ MyLock myLock ; public Thread2(MyLock myLock) { this.myLock = myLock; } @Override public void run() { myLock.objLockMethod1(); } }
/** * */ /** * <p>Title: ThreadMain</p> * <p>Description: </p> * <p>Company: </p> * @author 夏 杰 * @date 2015年12月17日 下午11:27:05 * @vesion 1.0 */ public class ThreadMain { /** * @param args */ public static void main(String[] args) { MyLock myLock = new MyLock(); new Thread(new Thread1(myLock)).start(); new Thread(new Thread2(myLock)).start(); } }
可以看出,类锁和对象锁不是同1个东西,一个是类的Class对象的锁,1个是类的实例的锁。也就是说:1个线程访问静态synchronized的时候,允许另一个线程访问对象的实例synchronized方法。反过来也是成立的,因为他们需要的锁是不同的。
相关文章推荐
- java thumbnail类库生成缩略图
- 集算器协助Java处理结构化文本之条件过滤
- 使用ant 的javac 运行时logback日志 pattern为 [null:-1] 的问题
- JAVA 学习笔记-01
- Java深入 - Java 内存分配和回收机制
- java实用基础
- java序列化和反序列化
- 关于java代码质量的问题
- 关于java代码质量的问题
- 详解Java的Hibernate框架中的List映射表与Bag映射
- 关于java代码质量的问题
- java系列: 对不起,JavaFX——Java 8目前还不能救你(zz)
- 欢迎使用CSDN-markdown编辑器
- Java多线程总结之由synchronized说开去(转)
- Java之美[从菜鸟到高手演变]之Exception
- Spring处理请求参数的几个小细节
- 数据库锁等待超时 java.sql.SQLException: Lock wait timeout exceeded
- 百度基础地图API- java.lang.UnsatisfiedLinkError、地图无法正确显示
- unable to fine a java virtual machine
- Java 初始化与清理