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

synchronized锁字符串

示例一

在没有使用synchronized锁的情况下:

import java.util.HashMap;
import java.util.Map;

public class NonSynchronizedSchoolExample {
    private static final Map<String, Integer> schoolCountMap = new HashMap<>();  // 存储每个学校的交卷数量

    public static void main(String[] args) {
        // 创建三个线程,模拟不同学校的学生交卷
        Thread thread1 = new Thread(new SubmitPaperTask("西华师范大学"), "Thread-1");
        Thread thread2 = new Thread(new SubmitPaperTask("西南石油大学"), "Thread-2");
        Thread thread3 = new Thread(new SubmitPaperTask("西南石油大学"), "Thread-3");

        thread1.start();
        thread2.start();
        thread3.start();
    }

    // 创建任务类,模拟学生交卷
    static class SubmitPaperTask implements Runnable {
        private final String school;

        public SubmitPaperTask(String school) {
            this.school = universityName;
        }

        @Override
        public void run() {
            // 直接访问并修改 HashMap,未考虑线程安全
            Integer count = schoolCountMap.get(school);
            if (count == null) {
                count = 0;  // 如果没有该学校的记录,默认值为0
            }
            // 模拟学生交卷
            System.out.println(school + " 的学生正在交卷...");
            try {
                Thread.sleep(1000);  // 模拟交卷时间
                schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量
                System.out.println(school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在没有使用synchronized的情况下,结果可能出现:

西华师范大学 的学生正在交卷...
西南石油大学 的学生正在交卷...
西华师范大学 的学生交卷完毕! 当前交卷数量: 1
西南石油大学 的学生交卷完毕! 当前交卷数量: 1
西南石油大学 的学生正在交卷...
西南石油大学 的学生交卷完毕! 当前交卷数量: 1

示例二

使用synchronized锁的情况下:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@RestController
public class SynchronizedSchoolController {

     // 存储每个学校的交卷数量
    private static final Map<String, Object> lockMap = new HashMap<>();  // 存储每个学校的锁对象

    // 接收交卷请求
    @GetMapping("/submitPaper/{school}")
    public String submitPaper(@PathVariable String school) {
        

        synchronized (this) {  // 锁住该学校的锁对象
            // 获取当前学校的交卷数量,如果没有则初始化为0
            Integer count = schoolCountMap.get(school);
            if (count == null) {
                count = 0;  // 如果没有该学校的记录,默认值为0
            }

            // 模拟学生交卷
            try {
                Thread.sleep(1000);  // 模拟交卷时间
                schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量
                return school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return "交卷失败!";
            }
        }
    }
}

在这种情况下,synchronized锁住的当前实例对象,在这种情况下,我们都每一个线程都是串行执行的。

示例三:

我现在想要改进代码,我可以用synchronized锁住(school)这个字符串,这样不同学校的线程就是并行的,相同学校的就是串行执行的

。。。
synchronized (school)
。。。

使用synchronized锁school字符串的情况下,如果我们使用http接口的发送去请求的话,spring的底层不是发送传递的“西华师范大学”“西南石油大学”这样的字符串常量,而是通过new String(“西华师范大学”)这样的方式去传递string对象。这种情况下锁的资源是三个不同的对象,没有同一个资源的互斥,就会发送并行。

这涉及到 字符串池(String Pool)和 字符串对象的创建方式:

字符串常量(字符串池)

在 Java 中,字符串常量(例如 "西华师范大学")会被存储在一个特殊的内存区域,称为 字符串池。当你创建一个字符串常量时,JVM 会检查池中是否已经存在相同的字符串对象,如果存在,就会返回池中的引用,否则将该字符串放入池中。

String str1 = "西华师范大学";  // 会被存储在字符串池中
String str2 = "西华师范大学";  // str1 和 str2 引用同一个对象

通过 new String() 创建字符串对象

通过 new String("西华师范大学") 创建的字符串对象不再从字符串池中获取对象,而是直接在堆内存中创建一个新的 String 对象。这意味着,每次调用 new String() 都会创建一个新的对象,即使其内容与字符串池中的常量相同。

String str1 = new String("西华师范大学");  // 会在堆中创建一个新的 String 对象
String str2 = new String("西华师范大学");  // str1 和 str2 引用不同的对象

所以直接synchronized (school)还是会出现异常。

 

示例四:

为了解决示例三的问题,我们想到了直接synchronized ()字符串常量。 因为字符串常量都是存放在字符串常量池当中的,是唯一的,能够形成资源互斥。

synchronized(school.intern())

但是字符串常量池里面的字符串是全局唯一的,可能会阻塞相同锁资源的不同操作,所以进一步改进:

我们通过ConcurrentMap创建一个锁对象

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

@RestController
public class SynchronizedSchoolController {

    // 使用 ConcurrentHashMap,确保线程安全
    private static final ConcurrentMap<String, Integer> schoolCountMap = new ConcurrentHashMap<>();  // 存储每个学校的交卷数量
    private static final ConcurrentMap<String, Object> lockMap = new ConcurrentHashMap<>();  // 存储每个学校的锁对象

    // 接收交卷请求
    @GetMapping("/submitPaper/{school}")
    public String submitPaper(@PathVariable String school) {
        // 获取每个学校的锁对象,确保每个学校有独立的锁
        Object lock = lockMap.computeIfAbsent(school, key -> new Object());

        synchronized (lock) {  // 锁住该学校的锁对象
            // 获取当前学校的交卷数量,如果没有则初始化为0
            Integer count = schoolCountMap.get(school);
            if (count == null) {
                count = 0;  // 如果没有该学校的记录,默认值为0
            }

            // 模拟学生交卷
            try {
                Thread.sleep(1000);  // 模拟交卷时间
                schoolCountMap.put(school, count + 1);  // 增加该学校的交卷数量
                return school + " 的学生交卷完毕! 当前交卷数量: " + (count + 1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return "交卷失败!";
            }
        }
    }
}

相关文章:

  • 语音直播交友app出海:语音直播交友系统软件源码搭建国际化发展技术层面分析
  • SHELL32!SHLoadPopupMenu函数分析之添加属性菜单项
  • Ubuntu22.04 - etcd的安装和使用
  • AI大模型发展对语音直播交友系统源码开发搭建的影响
  • python-leetcode-搜索二维矩阵 II
  • 实战:利用百度站长平台加速网站收录
  • Spring Boot 中事务的用法详解
  • 雷龙CS贴片式NAND芯片应用实践-大容量存储与多媒体设备的完美融合
  • Effective C++ 读书笔记(十二)
  • Perl 面向对象编程指南
  • 17-最长公共前缀
  • Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(1)
  • C++ 泛型编程之补充(class 和typename)
  • 【复习】Java集合
  • Vue2是如何利用Object.defineProperty实现数据的双向绑定?
  • 第十一章: vue2-3 生命周期
  • 《Operating System Concepts》阅读笔记:p62-p75
  • Uptime Kuma实现业务接口自定义逻辑监控
  • MySQL的数据类型
  • Java 虚拟机(JVM)方法区详解
  • 网站可以增加关键词吗/培训机构网站
  • 济南网站开发企业/网络营销方案
  • 新手如何做网站的教程/营销方案怎么写
  • 公众号引流推广吸粉方案/北京网站优化策略
  • 网站建设yankt/小红书搜索指数
  • 宁夏电力建设工程公司外部网站/好的在线crm系统