synchronized、volatile、Lock详解

叁歲伎倆 2022-05-31 00:44 272阅读 0赞

  在Java并发编程过程中,我们难免会遇到synchronizedvolatilelock,其中lock是一个类,而其余两个则是Java关键字。以下记录了小博开发过程中对这三者的理解,不足之处请多指教。

关于线程与进程请参考博文 以操作系统的角度述说线程与进程

synchronized

  synchronized是Java中的关键字,是一种同步锁。有以下几种用法:

1、修饰方法:在范围操作符之后,返回类型声明之前使用。每次只能有一个线程进入该方法,此时线程获得的是成员锁。

  1. public synchronized void syncMethod() {
  2. //doSomething
  3. }

2、修饰代码块:每次只能有一个线程进入该代码块,此时线程获得的是成员锁。

  1. public int synMethod(int arg){
  2. synchronized(arg) {
  3. //doSomething
  4. }
  5. }

3、修饰对象:如果当前线程进入,那么其他线程在该类所有对象上的任何操作都不能进行,此时当前线程获得的是对象锁。

  1. public class SyncThread implements Runnable {
  2. public static void main(String args[]) {
  3. SyncThread syncThread = new SyncThread();
  4. Thread therad1 = new Thread(syncThread, "therad1");
  5. Thread therad2 = new Thread(syncThread, "therad2");
  6. Thread therad3 = new Thread(syncThread, "therad3");
  7. therad1.start();
  8. therad2.start();
  9. therad3.start();
  10. }
  11. public void run() {
  12. synchronized (this) {
  13. System.out.println(Thread.currentThread().getName());
  14. }
  15. }
  16. }

4、修饰类:如果当前线程进入,那么其他线程在该类中所有操作不能进行,包括静态变量和静态方法,此时当前线程获得的是对象锁。

  1. public class syncClass {
  2. public void method() {
  3. synchronized(syncClass.class) {
  4. //doSomething
  5. }
  6. }
  7. }

volatile

  volatile 关键字的作用是禁止指令的重排序,强制从公共堆栈中取得变量的值,而不是从线程私有的数据栈中取变量的值。
volatilesynchronized的区别如下:

  • volatile 不会发生线程阻塞,而 synchronized 会发生线程阻塞。
  • volatile 只能修饰变量,而 synchronized 可以修饰方法、代码块等。
  • volatile 不能保证原子性(不能保证线程安全),而 synchronized 可以保证原子性。
  • volatile 解决的是变量在多线程之间的可见性,而 synchronized 解决的是多线程之间访问资源的同步性。

lock

  synchronized隐式锁,在需要同步的对象中加入此控制,而lock显示锁,需要显示指定起始位置和终止位置。

  • 使用lock时在finally中必须释放锁,不然容易造成线程死锁;而使用synchronized时,获取锁的线程会在执行完同步代码后释放锁(或者JVM会在线程执行发生异常时释放锁)。

  • 使用lock时线程不会一直等待;而使用synchronized时,假设A线程获得锁后阻塞,其他线程会一直等待。
  • lock可重入、可中断、可公平也可不公平;而synchronized可重入但不可中断、非公平。

锁的类型请参考博文 Java并发编程:Lock

发表评论

表情:
评论列表 (有 0 条评论,272人围观)

还没有评论,来说两句吧...

相关阅读

    相关 NIO详解(五):Buffer详解

    1. 概述 Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。缓冲区本质上是一块可以写入数据,然后可以从