Java中的synchronized锁是一种用于实现线程同步的机制,它可以保证在多线程环境下的数据同步和共享资源的安全访问。在使用synchronized锁的时候,我们需要注意其锁的升级过程,因为锁升级过程直接影响着程序的性能和效率。
一、synchronized锁的升级过程
synchronized锁的升级过程可以分为三种状态,分别是无锁状态、偏向锁状态和重量级锁状态。下面详细讲解每种状态:
- 无锁状态
在未经过任何同步操作的情况下,对象处于无锁状态,此时线程是可以直接访问该对象的成员变量和成员方法的。
- 偏向锁状态
如果只有一个线程直接进行加锁和解锁操作,那么就会出现偏向锁状态。在偏向锁状态下,锁会记录下持有偏向锁的线程ID,以后该线程访问同步块的时候就可以直接使用偏向锁而不需要再次操作同步机制。如果有其他线程访问该同步块,则会撤销偏向锁,升级为轻量级锁。
- 重量级锁状态
如果存在多个线程争夺同一个对象并且使用synchronized关键字进行加锁操作,那么就会出现重量级锁状态。在重量级锁状态下,锁会使用操作系统的互斥量来完成同步机制。当一个线程获取锁时,其他线程必须等待获得锁的线程释放锁后才能再次去争夺锁。
二、synchronized锁的升级过程示例
为了更好地理解synchronized锁的升级过程,下面给出两个示例,分别是偏向锁和重量级锁状态的示例。
- 偏向锁状态示例
public class SynchronizedDemo {
private static final int COUNT = 1_0000_0000;
private static Lock lock=new ReentrantLock();
private static int num = 0;
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
T1 t1 = new T1();
lock.lock();
while (--COUNT > 0) {
num++;
}
lock.unlock();
t1.start();
t1.join();
System.out.println("num:" + num);
System.out.println(System.currentTimeMillis() - start);
}
private static class T1 extends Thread {
@Override
public void run() {
lock.lock();
num += 10;
lock.unlock();
}
}
}
在这个示例中,主线程通过一个循环对变量num进行了多次累加操作,在执行完成后启动了一个子线程t1,t1线程的任务是对变量num进行加10操作。由于主线程对num进行了多次操作,因此这个场景无法完全满足偏向锁的条件,实际运行过程中也没有出现偏向锁状态,所有的操作都是重量级锁状态。
- 重量级锁状态
public class SynchronizedDemo {
private static final int COUNT = 1_0000_0000;
private static int num = 0;
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
T1 t1 = new T1();
synchronized (SynchronizedDemo.class) {
while (--COUNT > 0) {
num++;
}
}
t1.start();
t1.join();
System.out.println("num:" + num);
System.out.println(System.currentTimeMillis() - start);
}
private static class T1 extends Thread {
@Override
public void run() {
synchronized (SynchronizedDemo.class) {
num += 10;
}
}
}
}
在这个示例中,主线程对变量num进行多次累加操作的过程中使用了synchronized关键字,此时锁的状态为重量级锁,t1线程对num进行加10操作时,同样需要操作synchronized关键字,线程会被阻塞直到获得锁。
三、总结
如上述示例所示,在使用synchronized锁的过程中,应尽量减少线程之间对同一个对象的竞争,越少的竞争会带来更好的程序性能。同时,我们还需要注意synchronized锁的升级过程,尽量使线程的操作在偏向锁或者轻量级锁状态下完成,避免进入重量级锁状态,从而提高程序的效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java中synchronized锁的升级过程 - Python技术站