JAVA多线程之synchronized,对象锁,类锁
来源:互联网 发布:正规的淘宝模特兼职 编辑:程序博客网 时间:2024/05/21 09:23
JAVA内置锁:java内置锁的两种体现就是对象锁和类锁,java内置锁是一个互斥锁,同时只能被一个线程拿到,线程进入同步方法时自动获取内置锁,退出方法时,释放内置锁。当一个线程A拿到内置锁,其他线程只能等待A执行完毕释放锁,才能有机会获取内置锁进入同步方法。
对象锁:对象锁是用于对象实例方法,或者一个对象实例上的,每个对象实例只有一把锁,且各个对象实例的锁互不干扰。
类锁:类锁是用于类的静态方法或者一个类的class对象,类锁只有一把。
synchronized:用来修饰方法或者代码块,保证同一时刻只有一个线程执行被修饰的方法或代码块。
内置锁和synchronized的关系:被synchronized修饰的方法或者代码块,java会自动给这个方法或代码块加上内置锁,线程必须拿到这个锁才能访问被synchronized修饰的方法或代码块。
下面从synchronized的使用实例来加深对象锁和类锁的映像。
持有对象锁的synchronized实例:
package com.zw;/** * 对象锁: * 用于对象实例的方法,每一个JAVA的实例对象都有且只有一个内置锁,线程进入同步方法或同步代码块时自动获取锁。 * 类锁: * 用于静态方法,每个Class类只有一个类锁 * * 对象锁和类锁可同时出现,互不干扰 * @author Administrator * */public class TestSynchronized {public static void main(String[] args) {final TestSynchronized testSynchronized = new TestSynchronized();Thread t = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtestSynchronized.test1();}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtestSynchronized.test2();}});t.start();t2.start();}public synchronized void test1() {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t" + i);}}public void test2() {synchronized (this) {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("m" + i);}}}}
输出结果:
t 4
t 3
t 2
t 1
t 0
m 4
m 3
m 2
m 1
m 0
上面的实例中同时启动两个线程,分别调用不同的被synchronized修饰的方法。从输出结果中可以看出两个线程的执行顺序是线程t先执行完毕后t2才开始执行,这是因为当前只创建了一个实例对象testSynchronized,每个实例对象只有一把锁,同步方法的执行前提是线程必须得拿到内置锁。t先拿到了对象实例的内置锁,t2只能等t执行结束才能开始调用被 synchronized修饰的方法。
持有类锁的synchronized实例:
package com.zw;/** * 对象锁: * 用于对象实例的方法,每一个JAVA的实例对象都有且只有一个内置锁,线程进入同步方法或同步代码块时自动获取锁。 * 类锁: * 用于静态方法,每个Class类只有一个类锁 * * 对象锁和类锁可同时出现,互不干扰 * @author Administrator * */public class TestSynchronized {public static void main(String[] args) {final TestSynchronized testSynchronized = new TestSynchronized();Thread t = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubTestSynchronized.test1();}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtestSynchronized.test2();}});t.start();t2.start();}public static synchronized void test1() {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t" + i);}}public void test2() {synchronized (TestSynchronized.class) {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("m" + i);}}}}
输出结果:
t 4
t 3
t 2
t 1
t 0
m 4
m 3
m 2
m 1
m 0
从输出结果可以看出启动两个线程,还是t先执行,t2后执行,这是因为类锁只有一把,t先拿到,t2只能等待t结束。
同时持有类锁和对象锁的synchronized实例:
package com.zw;/** * 对象锁: * 用于对象实例的方法,每一个JAVA的实例对象都有且只有一个内置锁,线程进入同步方法或同步代码块时自动获取锁。 * 类锁: * 用于静态方法,每个Class类只有一个类锁 * * 对象锁和类锁可同时出现,互不干扰 * @author Administrator * */public class TestSynchronized {public static void main(String[] args) {final TestSynchronized testSynchronized = new TestSynchronized();Thread t = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubTestSynchronized.test1();}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtestSynchronized.test2();}});t.start();t2.start();}public static synchronized void test1() {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("t" + i);}}public void test2() {synchronized (this) {int i = 5;while(i-- > 0){try {Thread.sleep(1 * 1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("m" + i);}}}}
输出结果:
t 4
m 4
t 3
m 3
t 2
m 2
t 1
m 1
t 0
m 0
从输出结果可以看出两个线程交替执行,也就说明类锁和对象锁可同时出现,互不影响。
synchronized修饰方法和修饰代码块的区别
synchronized修饰方法,因为同一时刻只能有一个线程访问同步方法,其他线程必须排队等候,若是持有锁的线程没有退出方法,其他线程都无法访问同步方法,就会造成死锁。为了缓解这个问题(只是缓解,没有根本解决),修饰代码块的方式就出现了,这种方式可以避免锁住整个方法,只需锁住重要的部分就行。
- JAVA多线程之synchronized,对象锁,类锁
- java多线程之synchronized和锁对象
- Java多线程----java 对象锁(synchronized/lock)
- Java多线程之synchronized
- Java多线程之synchronized
- java多线程之synchronized
- java多线程之synchronized
- Java多线程之synchronized
- java 多线程锁synchronized
- Java多线程总结之 synchronized
- Java多线程之~~~~synchronized 方法
- (二)java多线程之synchronized
- 【Java基础】多线程之synchronized
- Java多线程之synchronized关键字
- JAVA多线程之Synchronized关键字
- 多线程之synchronized锁字符串对象的一个易错点
- java多线程设计wait/notify机制 (synchronized与对象锁)
- java多线程设计wait/notify机制 (synchronized与对象锁)
- linux copy_from/to_user原理
- HTML5: 标签的改变
- 约瑟夫环
- 关于WEB-INF目录不提供外部访问及JSP引用 js,css 文件路径问题
- iOS 如何优化项目
- JAVA多线程之synchronized,对象锁,类锁
- PHP-批量删除
- 动态代理(JDK实现)
- 安装kinect2_viewer遇到的各种bug的记录
- 锋利的jQuery(第2版)pdf
- 复制文本时追加自定义信息
- 配置PCA的一点总结12单片机
- 利用pywinauto模块打开一个应用,输入参数,点击应用中的按钮,获取数据
- 【OpenStack源码分析之七】openstack中的RPC请求分析