并发编程之synchronized之精髓
2023-10-11 02:29:09
在分布式/微服务架构盛行的今天,并发场景中使用synchronized似乎不再常见,但作为JDK 自带的并发,它在面试中仍频繁出现。因此,让我们重温synchronized,深入挖掘其背后的原理。
synchronized 的基本概念
synchronized是Java中用于实现并发控制的关键关键字,允许我们对共享数据进行同步访问。当一个线程进入synchronized代码块或方法时,它将获取该代码块或方法所属对象的锁,当其他线程试图访问该对象时,它们将被阻塞,直到锁被释放。
synchronized 的使用场景
synchronized通常用于保护共享数据,防止多个线程同时访问和修改这些数据,从而导致数据不一致或损坏。常见的synchronized使用场景包括:
- 多线程环境下对共享变量的访问和修改
- 多线程环境下的资源竞争(如线程间的同步和互斥)
- 多线程环境下的数据一致性控制
- 多线程环境下的锁竞争和死锁避免
synchronized 的实现原理
synchronized 是通过Java虚拟机(JVM)底层的监视器(monitor)机制来实现的。每个对象都与一个监视器相关联,监视器可以被多个线程同时访问,但同一时刻只有一个线程可以获得该监视器的锁。
当一个线程进入synchronized代码块或方法时,它会尝试获取该对象监视器的锁。如果锁可用,则该线程将成功获取锁并进入临界区(critical section),即synchronized代码块或方法的内部。如果锁不可用,则该线程将被阻塞,直到锁被释放。
当一个线程离开synchronized代码块或方法时,它会释放该对象监视器的锁,以便其他线程可以获取该锁并进入临界区。
synchronized 的锁竞争和性能优化
在并发编程中,锁竞争是一个常见的性能问题。当多个线程同时争夺同一把锁时,就会发生锁竞争。锁竞争会导致线程阻塞,从而降低系统的吞吐量和响应速度。
为了避免锁竞争,我们可以采取以下措施:
- 尽量减少synchronized代码块或方法的粒度,只对需要同步访问的数据进行同步。
- 使用乐观并发控制(OCC)技术来避免不必要的锁竞争。OCC技术允许多个线程同时访问和修改数据,但当一个线程试图提交修改时,它会检查数据是否被其他线程修改过。如果数据被修改过,则该线程的修改将被回滚。
- 使用无锁并发数据结构,如CAS(Compare-And-Swap)和原子变量,来避免锁竞争。无锁并发数据结构不需要使用锁,因此可以避免锁竞争和死锁问题。
总结
synchronized是Java中用于实现并发控制的关键关键字,它允许我们对共享数据进行同步访问,防止数据不一致或损坏。synchronized是通过Java虚拟机底层的监视器机制来实现的,每个对象都与一个监视器相关联,同一时刻只有一个线程可以获取该监视器的锁。
在并发编程中,锁竞争是一个常见的性能问题。为了避免锁竞争,我们可以尽量减少synchronized代码块或方法的粒度,使用乐观并发控制技术,以及使用无锁并发数据结构。
掌握synchronized的使用技巧,可以帮助我们编写出高性能、高并发性的Java程序。