当前位置: 首页 > article >正文

Java 关键字【synchronized】

Java 关键字【synchronized】

  1. 是什么

    synchronized是Java的一个关键字,是 Java 语言内置的同步机制,由 JVM 实现,它提供了一种互斥机制,用于线程同步,确保在同一时刻只有一个线程能访问被synchronized修饰的方法(代码块);当然这在多线程中才有发挥的空间,可以防止多个线程同时访问和修改共享数据,保持数据的一致性。

  2. 怎么用

    • 修饰代码块

      使用synchronized关键字来修饰一个代码块,语法为synchronized (对象表达式) {代码块}

      // 源码 java.lang.ClassLoader.class    
      protected Class<?> loadClass(String name, boolean resolve)
              throws ClassNotFoundException
          {
              // 为了保证类加载过程的原子性和正确性,使用了synchronized
              synchronized (getClassLoadingLock(name)) {
                  // First, check if the class has already been loaded
                  Class<?> c = findLoadedClass(name);
                  if (c == null) {
                      long t0 = System.nanoTime();
                      try {
                          if (parent != null) {
                              c = parent.loadClass(name, false);
                          } else {
                              c = findBootstrapClassOrNull(name);
                          }
                      } catch (ClassNotFoundException e) {
                          // ClassNotFoundException thrown if class not found
                          // from the non-null parent class loader
                      }
      
                      if (c == null) {
                          // If still not found, then invoke findClass in order
                          // to find the class.
                          long t1 = System.nanoTime();
                          c = findClass(name);
      
                          // this is the defining class loader; record the stats
                          PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                          PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                          PerfCounter.getFindClasses().increment();
                      }
                  }
                  if (resolve) {
                      resolveClass(c);
                  }
                  return c;
              }
          }
      
    • 修饰方法:

      当 synchronized 修饰一个实例方法时,它会锁定当前对象的实例

       // 源码 Thread类中的start()方法 
      /** 
      使用 synchronized 修饰 Thread 的 start 方法是为了保证线程状态转换的一致性、线程组操作的安全性以及避免并发执行 start0 方法,确保线程启动的过程是线程安全的,避免多个线程并发修改线程相关状态和调用 start0 方法导致的各种错误和异常。这种同步机制保证了 Thread 类在多线程环境下的正常工作和正确使用。
      **/
       public synchronized void start() {
              /**
               * This method is not invoked for the main method thread or "system"
               * group threads created/set up by the VM. Any new functionality 			  added
               * to this method in the future may have to also be added to the VM.
               *
               * A zero status value corresponds to state "NEW".
               */
              if (threadStatus != 0)
                  throw new IllegalThreadStateException();
      
              /* Notify the group that this thread is about to be started
               * so that it can be added to the group's list of threads
               * and the group's unstarted count can be decremented. */
              group.add(this);
      
              boolean started = false;
              try {
                  start0();
                  started = true;
              } finally {
                  try {
                      if (!started) {
                          group.threadStartFailed(this);
                      }
                  } catch (Throwable ignore) {
                      /* do nothing. If start0 threw a Throwable then
                        it will be passed up the call stack */
                  }
              }
          }
      
  3. 为啥可以这样用

    • 当一个线程访问被synchronized修饰的代码时,它首先检查锁是否可用。如果锁可用,线程会获取锁并进入代码块或者方法执行。如果锁不可用(已经被其他线程获取),当前线程会被阻塞,进入等待状态,直到锁被释放。
    • 线程执行完被synchronized修饰的代码,它会释放锁,使得其他等待的线程有机会获取锁并执行。
  4. 这样用的好处与坏处

    • 好处: 保证线程安全

    • 坏处: 带来一定的性能开销,因为线程的阻塞和唤醒操作需要消耗系统资源,而且过多的锁竞争会导致线程频繁的等待,降低程序的并发性能。

    • 建议: 只对真正需要同步的代码进行保护,尽量缩短synchronized代码块的范围。


http://www.kler.cn/a/467359.html

相关文章:

  • Vue3-跨层组件通信Provide/Inject机制详解
  • Jetpack Compose 学习笔记(四)—— CompositionLocal 与主题
  • MySQL(六)MySQL 案例
  • PDF文件提示-文档无法打印-的解决办法
  • Fabric部署-docker安装
  • Spring Boot - 日志功能深度解析与实践指南
  • 智慧招商宣传系统(源码+文档+部署+讲解)
  • 香橙派安装 opencv 4.9.0
  • C++文件流 例题
  • 电子应用设计方案86:智能 AI背景墙系统设计
  • 激活函数概述及对比
  • 计算机网络 (24)网际控制报文协议ICMP
  • Excel导出功能:vue2+SpringBoot
  • 4.3 最短路径问题:Dijkstra、Floyd
  • tensorflow 内存错误
  • NS4866 500mA 多功能锂电池充放电管理IC
  • django vue3实现大文件分段续传(断点续传)
  • unity学习3:如何从github下载开源的unity项目
  • 数字0、字符‘0’、转义字符‘\0’、NULL有什么区别?
  • Profinet转EtherNet/IP网关连接AB PLC的应用案例
  • Word如何设置整段背景色
  • 成立一家无人机培训机构需要哪些基础配置
  • 机器学习 - 线性回归
  • Http基础认证摘要认证
  • uniapp实现后端数据i18n国际化
  • [CTF/网络安全] 攻防世界 get_post 解题详析