博客
关于我
多线程--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/

    你可能感兴趣的文章
    Nacos配置中心集群原理及源码分析
    查看>>
    nacos配置自动刷新源码解析
    查看>>
    Nacos集群搭建
    查看>>
    nacos集群搭建
    查看>>
    Navicat for MySQL 查看BLOB字段内容
    查看>>
    Neo4j电影关系图Cypher
    查看>>
    Neo4j的安装与使用
    查看>>
    Neo4j(2):环境搭建
    查看>>
    Neo私链
    查看>>
    nessus快速安装使用指南(非常详细)零基础入门到精通,收藏这一篇就够了
    查看>>
    Nessus漏洞扫描教程之配置Nessus
    查看>>
    Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
    查看>>
    nestJS学习
    查看>>
    NetApp凭借领先的混合云数据与服务把握数字化转型机遇
    查看>>
    NetBeans IDE8.0需要JDK1.7及以上版本
    查看>>
    netcat的端口转发功能的实现
    查看>>
    netfilter应用场景
    查看>>
    netlink2.6.32内核实现源码
    查看>>
    Netpas:不一样的SD-WAN+ 保障网络通讯品质
    查看>>
    NetScaler的常用配置
    查看>>