synchronized用法与原理详解

介绍

在日常开发的过程中,为了提升业务处理的性能,我们常用多线程对代码进行逻辑改造,合理地使用多线程可以更好的利用计算资源。
因为每个线程都有自己的栈空间,所以只使用自己的线程上下文时不会有什么问题。但是大多数情况下,多线程的场景都需要线程间进行协作,当多个线程同时使用共享变量时,就涉及到主内存与线程工作内存间的同步。如何处理共享数据的线程安全问题?只要让线程一个个依次访问共享变量即可。这时,synchronized关键字就出场了。
synchronized关键字是用来控制线程同步的,保证多线程环境下,方法或代码块不被多个线程同时执行。

使用

synchronized关键字可以修饰方法和代码块,它的使用方法主要有以下几种:

分类 方法类型 上锁的对象 代码示例
方法 实例方法 实例对象 // 锁住的类的实例对象
public synchronized void method {
... ...
}
静态方法 类对象 // 静态方法直接和类关联,所以锁住的是类对象
public synchronized static void method {
... ...
}
代码块 * 当前类的实例对象 // 使用this时,锁住的是类的实例对象
synchronized(this) {
... ...
}
* 类对象 // 锁住的是类对象
synchronized(Demo.class) {
... ...
}
* 任意实例对象 // 锁住任意的实例对象,示例中锁住的是demo
Demo demo = new Demo();
synchronized(demo) {
... ...
}

如表格中所示,synchronized是通过锁住某些对象来实现线程同步的。当synchronized的使用方法不同时,被锁住的对象也不同。有两点值得注意:

  1. 当synchronized修饰代码块时,必须明确指定提供内部锁的对象。
  2. 线程必须持有锁才能工作,但同一时间只有一个线程可以持有锁,其他线程必须等待锁释放后才能再次尝试重新获取锁。

这么说可能会有点抽象,下面来看两个例子:

  1. 当锁住的是类对象时,所有类的实例在访问synchronized修饰的内容时都将被阻塞:
public class Demo implements Runnable {
   
    @Override
    public void run() {
   
        synchronized(Demo.class) {
   
            for (int i = 0; i < 3; i++) {
   
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
                try {
   
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
   
   
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值