首页 > 编程知识 正文

编写运行java程序步骤,简述java编译运行过程

时间:2023-05-05 15:19:01 阅读:166272 作者:4886

什么是响应编程,Java如何实现

在此,以唯一id知道的某个回答为例。 首先,要明确的是,一旦将HTTP请求发送到服务器并进行处理,就将响应写回到此请求的连接是完成此请求。 如下所示。

公共void请求(connection connection,http请求) )。

处理request并省略代码

connection.write(response; //完成响应

}

假设需要调用两个接口来获取答案、获取评论数和答案信息,传统代码可能会这样写。

//获取注释数

公共连接请求(connection connection,http请求) {

integer comment count=空;

try {

//从缓存中获取评论数,阻止IO

comment count=getcommnetcountfromcache (id;

}catch(exceptione ) {

try {

//如果缓存获取失败,则从数据库中获取,阻止IO

comment count=getvotecountfromdb (id;

}catch(exceptionex ) {

}

}

connection.write(commentcount;

}

//得到回答

publicvoidgetanswer (connection connection,HttpRequest request ) )。

//点赞数

Integer voteCount=null;

try {

//从缓存中获取点赞数,屏蔽IO

vote count=getvotecountfromcache (id;

}catch(exceptione ) {

try {

//如果缓存获取失败,则从数据库中获取,阻止IO

vote count=getvotecountfromdb (id;

}catch(exceptionex ) {

}

}

//从数据库获取回答信息,屏蔽IO

answer answer=getanswerfromdb (id;

组装响应

ResultVO response=new ResultVO (;

if (计数!=null ) {

response.setvotecount (vote count );

}

if (安瑟!=null ) {

response.setanswer(answer );

}

connection.write(response; //完成响应

}

在此实现中,进程只需要一个线程池来承载所有请求。 这种实现有两个弊端。

如果线程池IO被阻止,导致某个存储变慢或缓存被破坏,则所有服务器都将被阻止。 现在,假设注释缓存突然中断,全部都要访问数据库,请求变慢了。 唯一的线程池已满,无法处理获取答案的请求,因为线程必须等待I/o响应。

要取得回答信息,可以同时进行点赞数的取得和回答信息的取得。 不需要先取得点赞数再取得回答信息。

现在,NIO无阻塞IO正在普及。 有了无阻塞IO,响应编程就可以在不阻塞线程的情况下处理请求。 这是怎么实现的呢

传统的BIO在线程向Connection写入数据后,当前线程一直处于Block状态,直到返回响应,然后再执行响应后的操作。 NIO在线程将数据写入Connection后,在一个位置缓存返回响应后需要的内容和参数,然后直接返回。 如果回复响应,NIO的选择器的Read事件将处于就绪状态。 扫描Selector事件的线程将告诉您线程池中的数据已改善。 然后,线程池中的一个线程取出刚缓存的工作有参数,继续处理。

那么,在返回缓存响应后如何实现所需的内容和参数呢? Java本身提供了两种类型的接口:基于回调的Callback接口(Java 8引入的各种Functional Interface )和Future框架。

基于Callback的实现:

//得到回答

publicvoidgetanswer (connection connection,HttpRequest request ) )。

ResultVO resultVO=new ResultVO (;

getVote

CountFromCache(id, (count, throwable) - {

//异常不为null则为获取失败

if (throwable != null) {

//读取缓存失败就从数据库获取

getVoteCountFromDB(id, (count2, throwable2) - {

if (throwable2 == null) {

resultVO.setVoteCount(voteCount);

}

//从数据库读取回答信息

getAnswerFromDB(id, (answer, throwable3) - {

if (throwable3 == null) {

resultVO.setAnswer(answer);

connection.write(resultVO);

} else {

connection.write(throwable3);

}

});

});

} else {

//获取成功,设置voteCount

resultVO.setVoteCount(voteCount);

//从数据库读取回答信息

getAnswerFromDB(id, (answer, throwable2) - {

if (throwable2 == null) {

resultVO.setAnswer(answer);

//返回响应

connection.write(resultVO);

} else {

//返回错误响应

connection.write(throwable2);

}

});

}

});

}

可以看出,随着调用层级的加深,callback 层级越来越深,越来越难写,而且啰嗦的代码很多。并且,基于 CallBack 想实现获取点赞数量其实和获取回答信息并发是很难写的,这里还是先获取点赞数量之后再获取回答信息。

那么基于 Future 呢我们用 Java 8 之后引入的 CompletableFuture 来试着实现下。

//获取回答

public void getAnswer(Connection connection, HttpRequest request) {

ResultVO resultVO = new ResultVO();

//所有的异步任务都执行完之后要做的事情

CompletableFuture.allOf(

getVoteCountFromCache(id)

//发生异常,从数据库读取

.exceptionallyComposeAsync(throwable - getVoteCountFromDB(id))

//读取完之后,设置VoteCount

.thenAccept(voteCount - {

resultVO.setVoteCount(voteCount);

}),

getAnswerFromDB(id).thenAccept(answer - {

resultVO.setAnswer(answer);

})

).exceptionallyAsync(throwable - {

connection.write(throwable);

}).thenRun(() - {

connection.write(resultVO);

});

}

这种实现就看上去简单多了,并且读取点赞数量还有读取回答内容是同时进行的。

Project Reactor 在 Completableuture 这种实现的基础上,增加了更多的组合方式以及更完善的异常处理机制,以及面对背压时候的处理机制,还有重试机制。

每日一刷,轻松提升技术,斩获各种offer:

什么是响应式编程,Java 如何实现 相关文章

什么原因才导致 select * 效率低下的

面试官:“酷炫的秋天,说一下你常用的SQL优化方式吧。”合适的黑夜:“那很多啊,比如不要用SELECT *,查询效率低。巴拉巴拉...”面试官:“为什么不要用SELECT * 它在哪些情况下效率低呢”合适的黑夜:“SELECT * 它好像比写指定列名多一次全表查询吧,还多查了一些无用

linux配置DNS主从配置

DNS主从搭建 什么是DNS DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,使用的是UDP协议的53号端口,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。DNS就是这样的一位

Java(4) | 匿名对象

# 什么是匿名对象 匿名对象没有名字和赋值运算 new 类名称(); 创建对象的标准格式: 类名称 对象名 = new 类名称(); # 注意事项 匿名对象只能使用一次 所以如果确定某个对象只是用一次,则可以使用匿名对象 # 代码演示 package com.leerep.javabase.anonymou

MQ学习1

MQ(bilibili) MQ和RabbitMQ基础 1 什么是MQ ?举例:用户注册 ?原来: 用户--短信服务--邮件服务--数据库 ?多线程:用户--短信(1秒) ?用户--邮件(1秒) ?用户--数据库(1秒) ?消息队列:用户--数据库(1秒) ?用户--消息队列(MQ)(0.5秒) ?消息队列(MQ)--短信 ?消

Day8

1什么是构造函数 构造函数是bai一种特殊的成员函数du,它主要用于为对象分配存zhi储空间,对数据成dao员进zhuan行初始化.构造函数shu具有一些特殊的性质: (1)构造函数的名字必须与类同名; (2)构造函数没有返回类型,它可以带参数,也可以不带参数; (3)声明类对象

关于Java注解(annotation)的简单理解

一、什么是注解 从 JDK5 开始,Java增加对元数据的支持,也就是注解。简单理解就是代码里的特殊标志,这些标志可以在编译,类加载,运行时被读取,并执行相应的处理,以便于其他工具补充信息或者进行部署。 二、为什么要使用注解 注解可以被其他程序(比如:

RestHighLevelClient的使用

是什么 es官网推荐的es客户端组件RestHighLevelClient, 其封装了操作es的crud方法,底层原理就是模拟各种es需要的请求,如put,post,delete,get等方式 使用步骤 1.引入pom依赖 2.application.yml配置ES 3.查询 // 构建查询参数SearchSourceBuilder search

makefile终极奥义

什么是makefile? 或许很多 Winodws 的程序员都不知道这个东西,因为那些 Windows 的 IDE 都为你做了这个工作,但是一个好的和 professional 的程序员, makefile 还是要懂。这就好像现在有这么多的 HTML 的编辑器,但如果你想成为一个专业人士,你还是要了

HTTP请求响应过程

HTTP请求 HTTP是超文本传输协议,其定义了客户端与服务器端之间文本传输的规范。HTTP默认使用80端口,这个端口指的是服务端的端口,而客户端使用的端口是动态分配的。当我们没有指定端口访问时,浏览器会默认帮我们添加80端口。我们也可以自己指定访问端口如

你不知道的 Proxy

在从观察者模式到响应式的设计原理这篇文章中,眼睛大的柜子介绍了 observer-util 这个库如何使用 Proxy 来实现响应式。而对于 vue-next 项目中的 @vue/reactivity 模块,也是利用 Proxy 来实现响应式。因此,如果你要学习 @vue/reactivity 模块的话,就需要先掌握

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。