Java中,两个请求同时访问一个action或method,代码的执行顺序是怎么样的

首先看文章之前你可以在脑海中模拟一下,两个请求并发访问一个方法,从浏览器到后台的大致流程是怎么样的,模拟的越详细越好。

我相信很大一部分人可能都会被这个问题难住,不管是刚毕业的大学生,还是工作两三年的朋友们。

可能我们平时太多的关注业务逻辑,关注各种炫酷的框架,亦或者是公司太忙,忙到我们没时间成长等等等,从而忽略了这些最基础的东西。不过可能正是因为这些最基础的东西,才是我们为什么薪资比别人低了一点,为什么机会比别人少了一点,为什么差距和别人越来越大。

学而不思则罔,思而不学则殆。

  • 这个问题其实分两步
  • 第一步是用户点击页面,并发送请求到服务器的步骤,这个步骤很复杂,涉及到网络协议很多东西,我们暂且不讲。
  • 第二步就是服务器收到请求,我们代码执行的过程,我们具体说一下这一步。

如下图这个简单的方法

有两个请求并发访问,也就是说有两个线程同时准备进入方法printA()。那么问题来了

是线程1先进入方法执行完毕后再让线程2进入执行吗

不是的,是两个线程同时去执行这一段代码

那有同学可能会问了,如果两个线程同时进入这个方法,

线程1执行到a = a + 10;此时a的值为11,

然后线程2进入方法执行int a = 1; 那线程1打印出来a是不是就变成1了。

不是的,线程1打印a还是为11,为什么呢,因为a是定义在方法里面的,是局部变量。

然后每个线程是不是都有一个私有的本地内存(Local Memory),这个私有本地内存是不是存放这个局部变量的,答案是肯定的,既然赋值操作都是在我自己的地盘弄的,那肯定不会影响到别人。

但是如果我在这个类中加入一个全局变量,如下图

两个线程同时进入这个方法,那输出的c肯定是不一样的,为什么呢,相信你已经猜到了,没错。

这是因为线程之间的共享变量存储在主内存(Main Memory)中,变量c是全局变量,会放在主存中

类初始化的时候全局变量会被加载到主存中,线程1需要对c赋值计算的时候,从主存中拷贝一个c的副本,放到自己的私有内存中,计算完毕后c的值发生了变化,回写到主存中,这时候线程2需要对c赋值计算了,再把c拷贝一个副本到自己的私有内存里,计算完毕后,再回写到主存中,最后的结果就是对c进行了两次操作。其实这个过程就是线程之间的通讯过程

如下草图

  • 好了,差不多到这里这个简易的流程就算是结束了。涉及到了几个知识点,线程内存模型,全局变量和成员变量的区别。
  • 写这篇文章的目的是想帮助对这一块概念比较模糊的同学,大家都知道线程的定义,变量的定义,但是结合在一起可能会迷糊一点,这里借一个简单的小例子可以帮大家把学到的东西串起来。
  • 知其然,知其所以然,才可以更好的敲代码。
  • 写在最后。其实最近在网上看到的一些文章说实话水平挺low的,作者不知所云的去讲解一些东西,或者讲的是错的东西,经不起推敲,对初学者其实很不好,对工作一段时间,基础不牢固的同学更是有不好影响。这里建议大家还是理论+实践去学习,多多思考,多多总结。

  • 原创不易,希望大家转载可以标明出处哦,如果这篇文章对你有帮助,或者在工作上学习上有不清楚的知识点,就扫码关注一下公众号,我们可以好好的沟通交流,还会不定时的分享一些干货哦,谢谢。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
要在Java实现Elasticsearch两个字段之间的差值取top,您需要使用Elasticsearch的Java客户端库,例如Elasticsearch High Level REST Client。 首先,请确保您已经添加了Elasticsearch Java客户端库的依赖项。如果您使用Maven,请在pom.xml文件添加以下依赖项: ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.15.0</version> </dependency> ``` 接下来,您可以使用以下Java代码来实现该功能: ```java import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.avg.Avg; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; public class ElasticsearchExample { public static void main(String[] args) { // 创建Elasticsearch客户端 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder("localhost:9200")); // 创建搜索请求 SearchRequest searchRequest = new SearchRequest("your_index"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 设置查询条件 sourceBuilder.query(QueryBuilders.matchAllQuery()); // 设置聚合 sourceBuilder.aggregation( AggregationBuilders.terms("top_difference").field("field1").size(10) .subAggregation(AggregationBuilders.avg("avg_difference") .script("doc['field2'].value - doc['field1'].value")) ); searchRequest.source(sourceBuilder); try { // 执行搜索请求 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 处理聚合结果 Terms termsAgg = searchResponse.getAggregations().get("top_difference"); for (Terms.Bucket bucket : termsAgg.getBuckets()) { String fieldValue = bucket.getKeyAsString(); Avg avgDifference = bucket.getAggregations().get("avg_difference"); double averageDifference = avgDifference.getValue(); System.out.println("Field: " + fieldValue + ", Average Difference: " + averageDifference); } // 关闭Elasticsearch客户端 client.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 在上述代码,您需要将"localhost:9200"替换为您的Elasticsearch主机和端口。"your_index"应替换为您要执行查询的索引名称。"field1"和"field2"是您要比较的两个字段。 代码的查询部分使用了`QueryBuilders.matchAllQuery()`来匹配所有文档。您可以根据需要修改查询条件。聚合部分使用`AggregationBuilders`来构建聚合,然后通过循环遍历聚合结果来获取字段值和差值的平均值。 请注意,上述代码仅为示例,您可能需要根据您的实际情况进行适当的修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值