不同方面浅浅认识一下 Synchronized

Java中的synchronized关键字是一种用于线程同步的机制,它可以确保同一时间只有一个线程能够访问共享资源。本篇博客将从synchronized的基本用法、synchronized锁的对象、synchronized的可重入性、synchronized的锁粒度、synchronized与锁优化等多个方面来深入介绍Java中synchronized关键字的使用。

一、synchronized的基本用法

synchronized关键字可以应用于方法和代码块上,以下是synchronized的基本用法示例:

1.1 修饰方法

synchronized可以用于修饰方法,使得在调用该方法时,只有一个线程能够执行该方法,其他线程需要等待。

public synchronized void syncMethod() {
    // synchronized方法体
}
复制代码

1.2 修饰代码块

synchronized还可以用于修饰代码块,只有当线程获取到该代码块的锁时才能进入执行,其他线程需要等待。

public void syncBlock() {
    synchronized (this) {
        // synchronized代码块
    }
}
复制代码

二、synchronized锁的对象

synchronized锁的对象可以是类的实例对象、类对象、任意对象等。以下是synchronized锁的对象示例:

2.1 类的实例对象

当synchronized锁的对象是类的实例对象时,不同的线程对同一个实例对象的同步方法或同步代码块的访问将会被阻塞,因为它们都是使用同一个对象锁。

public synchronized void syncMethod() {
    // synchronized方法体
}

public void syncBlock() {
    synchronized (this) {
        // synchronized代码块
    }
}
复制代码

2.2 类对象

当synchronized锁的对象是类对象时,不同的线程对同一个类的同步方法或同步代码块的访问将会被阻塞,因为它们都是使用同一个类锁。

public static synchronized void syncMethod() {
    // synchronized方法体
}

public void syncBlock() {
    synchronized (SynchronizedDemo.class) {
        // synchronized代码块
    }
}
复制代码

2.3 任意对象

当synchronized锁的对象是任意对象时,不同的线程对同一个对象的同步方法或同步代码块的访问将会被阻塞,因为它们都是使用同一个对象锁。

public synchronized void syncMethod() {
    // synchronized方法体
}

public void syncBlock() {
    Object lock = new Object();
    synchronized (lock) {
        // synchronized代码块
    }
}
复制代码

三、synchronized的可重入性

synchronized具有可重入性,即一个线程已经获得了一个对象的锁,再次请求该对象的锁时仍然可以获得该锁。

public synchronized void syncMethod() {
    syncMethod2();
    // synchronized方法体
}
复制代码

在上面的代码中,syncMethod2()方法也是一个synchronized方法,当syncMethod()方法调用syncMethod2()方法时,它仍然可以获取到该对象的锁,因为锁是可重入的。

四、synchronized的锁粒度

synchronized锁的粒度大小是需要考虑的一个问题,粒度过大会导致性能下降,粒度过小又可能导致死锁。以下是synchronized锁的粒度示例:

4.1 对象锁

对象锁的粒度最细,它只锁定对象中的一个方法或代码块。

public synchronized void syncMethod() {
    // synchronized方法体
}

public void syncBlock() {
    synchronized (this) {
        // synchronized代码块
    }
}
复制代码

4.2 类锁

类锁的粒度比对象锁大,它锁定的是整个类的同步方法或同步代码块。

public static synchronized void syncMethod() {
    // synchronized方法体
}

public void syncBlock() {
    synchronized (SynchronizedDemo.class) {
        // synchronized代码块
    }
}
复制代码

五、synchronized与锁优化

Java中的synchronized关键字在使用时需要考虑锁的粒度和性能问题,同时也有一些锁优化的技巧可以使用,以下是synchronized与锁优化的示例:

5.1 减小锁粒度

如果使用了对象锁,可以将锁的粒度减小到对象的某个属性上,以减少锁的粒度,从而提高程序的并发性。

public void syncBlock() {
    synchronized (lock) {
        // synchronized代码块
    }
}

public void syncBlock2() {
    synchronized (lock.getProperty()) {
        // synchronized代码块
    }
}
复制代码

5.2 双重检查锁定

双重检查锁定技术可以减少锁的粒度,提高程序的并发性。

public class Singleton {
    private volatile static Singleton instance;
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
复制代码

在以上代码中,通过双重检查锁定的方式,可以确保Singleton实例只被创建一次,并且提高了程序的并发性能。

5.3 锁消除

在一些情况下,编译器会自动消除一些不必要的锁,以提高程序的并发性能。

public void syncMethod() {
    StringBuilder sb = new StringBuilder();
    sb.append("a").append("b").append("c");
    // sb对象没有被其他线程共享,可以消除锁
    synchronized (sb) {
        // synchronized代码块
    }
}
复制代码

以上代码中,由于sb对象没有被其他线程共享,因此编译器可以自动消除synchronized。

六、synchronized的局限性和替代方案

synchronized虽然是Java中一个非常重要的同步机制,但它也有一些局限性和替代方案。

6.1 局限性

  • synchronized只能保证单个线程的同步,无法保证多个线程之间的协作;
  • synchronized在多线程并发访问下会导致性能下降;
  • synchronized在死锁等异常情况下可能导致程序出现问题。

6.2 替代方案

Java中有许多替代方案可以代替synchronized实现同步,以下是一些常用的替代方案:

  • Lock:Lock是Java中提供的一个新的同步机制,它可以替代synchronized实现线程同步,具有更好的扩展性和性能;
  • Atomic:Atomic提供了一些原子操作,可以实现一些线程安全的操作;
  • ConcurrentHashMap:ConcurrentHashMap是Java中线程安全的Map,可以实现高并发访问;
  • Semaphore:Semaphore是一种计数信号量,可以用来控制对公共资源的访问。

七、总结

synchronized是Java中非常重要的同步机制,它可以保证多个线程之间的安全协作,但在使用时需要考虑锁的粒度和性能问题,同时也有一些锁优化的技巧可以使用。

除了synchronized之外,Java中还有许多替代方案可以实现线程同步,包括Lock、Atomic、ConcurrentHashMap等。在实际应用中,需要根据具体的场景选择适合的同步机制来保证程序的正确性和性能。会在后续讲解不同锁结构

全部评论
认识了,原来挺厉害的
1 回复 分享
发布于 2023-03-18 11:00 山东
谢谢大佬分享
1 回复 分享
发布于 2023-03-18 11:21 山东

相关推荐

11-09 14:54
已编辑
华南农业大学 产品经理
大拿老师:这个简历,连手机号码和照片都没打码,那为什么关键要素求职职位就不写呢? 从上往下看,都没看出自己到底是产品经理的简历,还是电子硬件的简历? 这是一个大问题,当然,更大的问题是实习经历的描述是不对的 不要只是去写实习流程,陈平,怎么去开会?怎么去讨论? 面试问的是你的产品功能点,是怎么设计的?也就是要写项目的亮点,有什么功能?这个功能有什么难处?怎么去解决的? 实习流程大家都一样,没什么优势,也没有提问点,没有提问,你就不得分 另外,你要明确你投的是什么职位,如果投的是产品职位,你的项目经历写的全都是跟产品无关的,那你的简历就没用 你的面试官必然是一个资深的产品经理,他不会去问那些计算机类的编程项目 所以这种四不像的简历,在校招是大忌
点赞 评论 收藏
分享
牛客339922477号:都不用reverse,直接-1。一行。啥送分题
点赞 评论 收藏
分享
点赞 9 评论
分享
牛客网
牛客企业服务