透彻理解 Java synchronized 对象锁和类锁的区别
来源:互联网 发布:燕郊seo 编辑:程序博客网 时间:2024/05/29 13:16
synchronized 加到 static 方法前面是给class 加锁,即类锁;而synchronized 加到非静态方法前面是给对象上锁。这两者的区别我用代码来演示下:
- 对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。
在Task2 中定义三个方法 doLongTimeTaskA和doLongTimeTaskB是类锁,而doLongTimeTaskC是对象锁。
public class Task2 { public synchronized static void doLongTimeTaskA() { System.out.println("name = " + Thread.currentThread().getName() + ", begain"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("name = " + Thread.currentThread().getName() + ", end"); } public synchronized static void doLongTimeTaskB() { System.out.println("name = " + Thread.currentThread().getName() + ", begain"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("name = " + Thread.currentThread().getName() + ", end"); } public synchronized void doLongTimeTaskC() { System.out.println("name = " + Thread.currentThread().getName() + ", begain"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("name = " + Thread.currentThread().getName() + ", end"); }
三个线程的代码如下:
class ThreadA extends Thread{ private Task2 mTask2; public ThreadA(Task2 tk){ mTask2 = tk; } public void run() { mTask2.doLongTimeTaskA(); }}class ThreadB extends Thread{ private Task2 mTask2; public ThreadB(Task2 tk){ mTask2 = tk; } public void run() { mTask2.doLongTimeTaskB(); }}class ThreadC extends Thread{ private Task2 mTask2; public ThreadC(Task2 tk){ mTask2 = tk; } public void run() { mTask2.doLongTimeTaskC(); }}
main函数中执行代码如下:
Task2 mTask2 = new Task2(); ThreadA ta = new ThreadA(mTask2); ThreadB tb = new ThreadB(mTask2); ThreadC tc = new ThreadC(mTask2); ta.setName("A"); tb.setName("B"); tc.setName("C"); ta.start(); tb.start(); tc.start();
执行的结果如下:
name = A, begain, time = 1487311199783name = C, begain, time = 1487311199783name = C, end, time = 1487311200784name = A, end, time = 1487311200784name = B, begain, time = 1487311200784name = B, end, time = 1487311201784
可以看出由于 doLongTimeTaskA和doLongTimeTaskB都是类锁,即同一个锁,所以 A和B是按顺序执行,即同步的。而C是对象锁,和A/B不是同一种锁,所以C和A、B是 异步执行的。(A、B、C代指上面的3中方法)。
我们知道对象锁要想保持同步执行,那么锁住的必须是同一个对象。下面就修改下上面的来证明:
Task2.java不变,修改ThreadA 和 ThreadB 如下:
class ThreadA extends Thread{ private Task2 mTask2; public ThreadA(Task2 tk){ mTask2 = tk; } public void run() { mTask2.doLongTimeTaskC(); }}class ThreadB extends Thread{ private Task2 mTask2; public ThreadB(Task2 tk){ mTask2 = tk; } public void run() { mTask2.doLongTimeTaskC(); }}
main方法如下:
Task2 mTaska = new Task2(); Task2 mTaskb = new Task2(); ThreadA ta = new ThreadA(mTaska ); ThreadB tb = new ThreadB(mTaskb ); ta.setName("A"); tb.setName("B"); ta.start(); tb.start();
结果如下:
name = A, begain, time = 1487311905775name = B, begain, time = 1487311905775name = B, end, time = 1487311906775name = A, end, time = 1487311906775
从结果看来,对象锁锁的对象不一样,分别是mTaska , mTaskb,所以线程A和线程B调用 doLongTimeTaskC 是异步执行的。
但是,类锁可以对类的所有对象的实例起作用。只需修改ThradA
和 ThreadB,main 方法不做改变,修改如下:
class ThreadA extends Thread{ private Task2 mTask2; public ThreadA(Task2 tk){ mTask2 = tk; } public void run() { //mTask2.doLongTimeTaskC(); mTask2.doLongTimeTaskA(); }}class ThreadB extends Thread{ private Task2 mTask2; public ThreadB(Task2 tk){ mTask2 = tk; } public void run() { //mTask2.doLongTimeTaskC(); mTask2.doLongTimeTaskA(); }}
结果如下:
name = A, begain, time = 1487312239674name = A, end, time = 1487312240674name = B, begain, time = 1487312240674name = B, end, time = 1487312241674
可以看出 在线程A执行完doLongTimeTaskA方法后,线程B才会获得该类锁接着去执行doLongTimeTaskA。也就是说,类锁对所有的该类对象都能起作用。
总结:
1. 如果多线程同时访问同一类的 类锁(synchronized 修饰的静态方法)以及对象锁(synchronized 修饰的非静态方法)这两个方法执行是异步的,原因:类锁和对象锁是2中不同的锁。
2. 类锁对该类的所有对象都能起作用,而对象锁不能。
- 透彻理解 Java synchronized 对象锁和类锁的区别
- 深入理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Java多线程总结(二):理解对象锁 & synchronized和Lock的区别
- java synchronized的理解以及内置锁和对象锁
- 透彻理解Java中的++运算(x++和++x的区别)
- Java Synchronized获得类的锁和获得对象的锁有什么区别呢?
- 理解synchronized对象锁
- java synchronized锁的理解
- JAVA Synchronized 关键字锁实例和锁CLASS对象的区别
- JAVA Synchronized 关键字锁实例和锁CLASS对象的区别
- 关于synchronized,对象锁的理解
- synchronized与static synchronized 的区别、synchronized在JVM底层的实现原理及Java多线程锁理解
- synchronized与static synchronized 的区别、synchronized在JVM底层的实现原理及Java多线程锁理解 (r)
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- java多线程-synchronized对象和方法的区别
- JavaScript基础——变量、数据类型
- Asp.Net MVC4.0 官方教程 入门指南之六--查看Edit方法和Edit视图
- apk优化-apk瘦身
- unity ios打包真机调试 Shader.Find()找不到问题
- subline快捷键的使用
- 透彻理解 Java synchronized 对象锁和类锁的区别
- iOS 集成tensorflow
- 聊聊并发(八)——Fork/Join框架介绍
- 备忘录模式
- linux 下tomcat6 配置为服务
- java中的抽象类和接口区别
- LeetCode 22. Generate Parentheses
- SVN uuid 报错解决方法
- linux centos6.5下安装svn方法