博客
关于我
多线程--Synchronized
阅读量:612 次
发布时间:2019-03-12

本文共 1793 字,大约阅读时间需要 5 分钟。

为什么要使用 synchronized

在并发编程中,线程安全问题是很常见的,主要形式包括共享数据和多线程同时操作共享数据。为了应对这些挑战,Java提供了synchronized关键字,它在以下方面发挥着重要作用:

  • 线程互斥:保证在任何时刻,只有一个线程能够执行同步代码。
  • 可见性:确保共享变量的修改能够及时可见,类似于volatile关键字。
  • 例如,在下面的代码中,如果不使用synchronized,可能会导致火车票重复出售的问题:

    public class TestDemo implements Runnable {    private volatile int count = 100;    @Override    public void run() {        while (count > 0) {            Thread.sleep(50);            sale();        }    }    public void sale() {        if (count > 0) {            System.out.println(Thread.currentThread().getName() + "出售 :" + (100 - count + 1));            count--;        }    }}

    synchronized 的实现原理

    synchronized 的作用机制可以分为以下几个方面:

    • 原子性:确保线程对共享资源的访问是原子操作,避免由于线程调度而导致的竞态条件。
    • 可见性:通过 EnsureIntrinsicLocks 到主内存(当获取锁时)和 UnlockToMemory palpate(解锁前)来保证共享变量的修改能够及时可见。
    • 有序性:排除重排序问题,确保线程间操作的有序性。

    synchronized 的三种应用方式

    在 Java 中,synchronized 锁可以应用在三个不同的方式中:

  • 普通同步方法(实例方法)

    • 锁是当前实例对象。
    • 使用 synchronized修饰方法时,进入方法前需要获取当前实例对象的锁。
    public synchronized void sale() {    if (count > 0) {        System.out.println("窗口一出售 :" + (100 - count));        count--;    }}
  • 静态同步方法

    • 锁是当前类对象。
    • 使用 synchronized修饰静态方法时,进入方法前需要获取当前类对象的锁。
    public static synchronized void sale() {    if (count > 0) {        System.out.println("窗口一出售 :" + (100 - count));        count--;    }}
  • 同步代码块

    • 锁是括号内的对象。
    • 在代码块中使用 synchronized时,进入方法前需要获取括号内对象的锁。
  • private Object object = new Object();public void sale() {    synchronized (object) {        if (count > 0) {            System.out.println("窗口一出售 :" + (100 - count));            count--;        }    }}

    synchronized 的 JDK 版本优化

    在 JDK 1.6 之前,synchronized实现的加锁和解锁操作非常重量级,会导致线程上下文切换和额外性能开销。新版本中,synchronized实现了偏向锁机制,结合轻量级锁和冲突检测机制(cas),从而大幅降低锁的开销。

    synchronized 的可重入性

    synchronized是支持可重入锁设计的。这意味着一个线程在持有一个对象锁的情况下,其它线程同样可以请求该对象锁。但必须注意,如果请求的是同一个对象锁,一定会等待;如果请求的是不同的对象锁,则会立即获取。这种方式避免了死锁,而不会导致资源浪费。

    转载地址:http://bwwaz.baihongyu.com/

    你可能感兴趣的文章
    npm error Missing script: “server“npm errornpm error Did you mean this?npm error npm run serve
    查看>>
    npm error MSB3428: 未能加载 Visual C++ 组件“VCBuild.exe”。要解决此问题,1) 安装
    查看>>
    npm install digital envelope routines::unsupported解决方法
    查看>>
    npm install 卡着不动的解决方法
    查看>>
    npm install 报错 EEXIST File exists 的解决方法
    查看>>
    npm install 报错 ERR_SOCKET_TIMEOUT 的解决方法
    查看>>
    npm install 报错 fatal: unable to connect to github.com 的解决方法
    查看>>
    npm install 报错 no such file or directory 的解决方法
    查看>>
    npm install 权限问题
    查看>>
    npm install报错,证书验证失败unable to get local issuer certificate
    查看>>
    npm install无法生成node_modules的解决方法
    查看>>
    npm install的--save和--save-dev使用说明
    查看>>
    npm node pm2相关问题
    查看>>
    npm run build 失败Compiler server unexpectedly exited with code: null and signal: SIGBUS
    查看>>
    npm run build报Cannot find module错误的解决方法
    查看>>
    npm run build部署到云服务器中的Nginx(图文配置)
    查看>>
    npm run dev 报错PS ‘vite‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
    查看>>
    npm scripts 使用指南
    查看>>
    npm should be run outside of the node repl, in your normal shell
    查看>>
    npm start运行了什么
    查看>>