日常思考-多个用户做出同样的请求,该请求在代码中调用同一个方法,那么请问服务器是怎么处理的?

多线程并发的处理,这里指的是服务器端,也就是 Java 的处理,与页面无关。

首先,当多个请求同时到达服务器时,服务器会分配线程来执行每个请求(如果请求数量太多,能用的线程有限,则会进行排队)。所以请求和请求之间首先是一个线程隔离的环境

每个线程都会按照同样的顺序执行同样的代码(这里简单的不考虑分支),在执行代码的过程中,线程会访问和操作各种各样的对象和变量。

所以这里就有一个问题:我怎么知道多个线程会不会访问到同一个对象,或者同一个变量呢?如果这样的事情发生了,可能会产生什么后果呢?

在详细解释这个问题之前,首先需要明确一个简单的原则:任何对象都可以被任意多个线程访问,这是代码的自由性决定的。但更重要的是,我们可以让对象主动掌控线程对自己的访问。

最简单的控制方式就是 synchronized,意即同时只允许一个线程访问,其它线程必须先等待。当 synchronized 用在方法上时,表示同一时间只允许一个线程执行这个方法。

那么是否意味着服务器上的所有方法都必须是synchronized的呢?不是。当一个方法执行时,所有的变量和参数都会保存在一个叫做堆栈的内存空间,这个内存空间是线程独享的,所以线程之间不会相互冲突。例如:

java 复制代码
public void hello(String name) {
    String greetings = "Hello, " + name;
    System.out.println(greetings);
}

当多个线程执行 hello() 方法时,每个线程都会在自己的堆栈中存放 name 参数和 greetings 变量。其中 greetings 变量是在方法内定义的,一个线程中的 greetings 变量与另一个线程中的 greetings 变量将是完全隔离的,不会相互影响。

堆栈是线程独享的,但是放入堆栈的内容则未必。像上面的例子,greetings 变量是线程自己创建的,所以其它线程访问不到,但 name 参数则未必,有可能多个线程在执行这个方法时,收到的 name 参数是同一个对象。这时候如果方法里面要修改这个对象,那就要小心了。

相关推荐
牧瀬クリスだ2 分钟前
YAML配置详解:SpringBoot实战指南
java·spring·yml
Su5734 分钟前
RuoYi + RAGFlow 搭建私有化知识库完整集成实践(二)
java
wechatbot88810 分钟前
极客互动企业微信 SCRM 自动运营平台效果实测
java·微信·企业微信·rpa
需要82614 分钟前
JVM 内存区域与对象创建:一次 GC 从哪来
java·jvm·spring boot·spring·servlet·tomcat
懂软件的胡子个哥15 分钟前
微信机器人为什么需要“回复候选”而不是所有 AI 内容直接发送
运维·微信·自动化·wechatapi·个人微信号二次开发
云贝贝贝36 分钟前
腾讯云 TDSQL(MySQL 版)性能优化与慢查询排障实战 6 招
运维·腾讯云
事圆则缓38 分钟前
Java 转 Kotlin 的 Android 迁移路线
java
Lsetea42 分钟前
证书没到期却报certificate has expired:OpenSSL定位中间证书与系统时间
运维·https·ssl证书·openssl·证书链
计算机毕设定制辅导-无忧学长44 分钟前
《基于Vue的流浪动物救助中心管理系统的设计与实现》
java·vue.js·spring boot·流浪动物救助中心管理系统
Mikko71 小时前
jackson-databind 升到 2.21.6 就安全了吗?jackson-core 是另一个坐标,它那条 high 全局库至今没收
java·后端·安全·json