synchronized
同步锁(synchronized)是Java中一种非常常见的同步机制,它可以保证多个线程对共享资源的访问互斥性。在本文中,我们将深入探讨synchronized的实现原理,包括锁的获取、释放以及锁的升级等关键概念。
- 锁的获取与释放
synchronized关键字用于修饰方法或代码块,当一个线程进入被synchronized修饰的方法或代码块时,它会尝试获取锁。如果锁已经被其他线程持有,那么当前线程将会阻塞等待,直到锁被释放。
锁的获取过程如下:
a. 当一个线程执行到synchronized关键字修饰的方法或代码块时,它首先会检查当前对象是否为null。如果为null,说明这是一个类级别的同步方法或代码块,此时会创建一个新的锁对象并将其赋值给this。
b. 如果当前对象不为null,说明这是一个实例级别的同步方法或代码块。此时,线程会调用对象的synchronized()
方法来获取锁。synchronized()
方法会返回一个锁对象,这个锁对象就是当前线程所持有的锁。
c. 当一个线程成功获取到锁后,它就可以安全地访问共享资源了。但是需要注意的是,当线程完成对共享资源的操作后,必须显式地释放锁,以便其他线程能够获取到锁并继续执行。
锁的释放过程如下:
a. 当一个线程完成对共享资源的操作后,它需要显式地释放锁。释放锁的方式有两种:使用return
语句和使用finally
子句。如果使用return
语句,那么在方法或代码块结束前必须释放锁;如果使用finally
子句,那么无论方法或代码块是否正常执行完毕,都会释放锁。
b. 当一个线程释放锁后,其他等待该锁的线程就可以重新竞争该锁了。如果当前没有其他线程正在等待该锁,那么锁对象会被自动回收。否则,下一个请求该锁的线程将会获得该锁并继续执行。
- 锁的升级
当一个线程在执行synchronized方法或代码块时遇到以下情况之一时,它会升级为重量级锁:
a. 当一个线程试图获取一个已被另一个线程持有的轻量级锁时。轻量级锁是通过CAS操作实现的在Java中,synchronized关键字用于实现线程同步。当一个线程进入被synchronized修饰的方法或代码块时,它会尝试获取锁。如果锁已经被其他线程持有,那么当前线程将会阻塞等待,直到锁被释放。
synchronized关键字有两种使用方式:对象级别和方法级别。对象级别的synchronized是针对整个类的,而方法级别的synchronized是针对类中的某个方法的。
当一个线程进入被synchronized修饰的方法或代码块时,它会首先检查当前对象是否为null。如果为null,说明这是一个类级别的同步方法或代码块,此时会创建一个新的锁对象并将其赋值给this。如果当前对象不为null,说明这是一个实例级别的同步方法或代码块。此时,线程会调用对象的synchronized()方法来获取锁。synchronized()方法会返回一个锁对象,这个锁对象就是当前线程所持有的锁。
当一个线程成功获取到锁后,它就可以安全地访问共享资源了。但是需要注意的是,当线程完成对共享资源的操作后,必须显式地释放锁,以便其他线程能够获取到锁并继续执行。
锁的释放过程如下:
a. 当一个线程完成对共享资源的操作后,它需要显式地释放锁。释放锁的方式有两种:使用return语句和使用finally子句。如果使用return语句,那么在方法或代码块结束前必须释放锁;如果使用finally子句,那么无论方法或代码块是否正常执行完毕,都会释放锁。
b. 当一个线程释放锁后,其他等待该锁的线程就可以重新竞争该锁了。如果当前没有其他线程正在等待该锁,那么锁对象会被自动回收。否则,下一个请求该锁的线程将会获得该锁并继续执行。
在Java中还有一种更高级的同步机制叫做“偏向锁”。偏向锁适用于那些只有一个线程访问同步代码块的情况。当一个线程首次访问一个偏向锁保护的对象时,JVM会将该对象的内部状态设置为偏向模式,并将对象头中的Mark Word字段设为指向当前线程的栈帧地址。这样一来,当其他线程也想访问这个对象时,它们会发现这个对象已经被锁定了,于是就会直接跳过同步代码块,而不需要进行加锁操作。这种方式可以提高程序的执行效率
- 点赞
- 收藏
- 关注作者
评论(0)