一、Callcable与Future
Callable + FutureTask = Future + Runnable ——>将callable赋值给futuretask,可以通过Runnable去获取线程执行任务代码,future去获取异步执行的结果。
1、Runnable封装一个异步运行的任务,可以把它想象成为一个没有参数和返回值的异步方法。Callable与Runnable类似,但是有返回值。Callable接口是一个参数化的类型。只有一个方法call()。
类型参数是返回值的类型;
call():将运行一个将产生结果的任务;
2、Future保存异步计算的结果。启动一个计算后,可以在Future对象交给某个线程。Future对象的所有者在结果计算好之后就可以获得它。
get()方法的调用被阻塞,直到计算完成或者时间超过指定的时间为止;
idDone()方法可以判断计算是够还在进行;
Cancel()方法可以取消计算;
3、FutureTask包装器可以将Callable转换为Future和Runnable,可以同时实现两者的接口。
二、执行器(线程池)
构建一个新的线程是需要一定的代价的。如果程序中创建了大量生命周期很短的线程,那么就应该使用线程池。将Runnable对象交给线程池,就会有一个线程调用run方法。当run方法退出时,线程不会死亡,而是在池中准备下一个请求提供服务。
执行器(Executor)类中有许多静态工厂方法用来构建线程池。
1、线程池
表格中前3个方法返回实现了ExecutorService接口的ThreadPoolExecutor类的对象。可以用下面的方法之一将一个Runnable对象或者Callable对象提交给ExecttorService:
当用完一个线程池的时候,调用shutdown。该方法启动该池的关闭序列。被关闭的执行器不再接受新的任务,当所有的任务都完成之后,线程中的线程死亡。
2、预定执行
ScheduledExecutorService接口具有为预定执行或重复执行任务而设计的方法。它是一种允许使用线程池机制的java.util.Timer的泛化。表格中最后两个方法将返回实现了ScheduledExecutorService接口的对象。
schedule:预定在指定的时间之后执行任务;
scheduleAtFixedRate:预定在初始的延迟结束后,周期性地运行给定的任务;
schedulewithFixedDelay:预定在初始的延迟结束后周期性地运行给定的任务,两次调用之间有长度为delay的延迟;
3、控制任务组
使用执行器可以控制一组相关任务。
invokeAny:提交所有对象到一个Callable对象的集合中,并返回某个已经完成了的任务的结果。无法知道返回的究竟是哪个任何的结果;
invokeAll:提交所有对象到一个Callable对象的集合中,并返回一个Future对象的列表;
ExecutorCompletionService:构建一个执行器完成服务来收集给定执行器的结果
4、Fork-Join框架
通过将任务拆分为子项目使用不同的处理器来使操作并行运行。如果需要采用框架来完成这种递归计算,需要提供一个扩展RecursiveTask的类(计算生成一个类型为T的结果)或者提供一个扩展RecursiveAction的类(不产生任何结果),再覆盖compute方法来生成并调用子任务并合并其结果。
invokeAll:接收很多任务并阻塞,直到这些任务都已经完成;
join方法将生成结果,对子任务应用join方法并返回其总和;
ForkJoinPool pool = new ForkJoinPool();
三、同步器
java.util.concurrent包包含了几个能帮助人们管理相互合作的线程集的类。
1、信号量
一个信号量管理许多许可证。为了通过信号量,线程通过调用acquire请求许可。许可不是实际的对象,仅仅是一个计数。其他线程可以通过release来释放许可。
2、倒计时门栓
让一个线程集等待直到计数变为0。倒计时门栓是一次性的,一旦计数为0,就不能再重用了。
3、障栅
4、交换器
5、同步队列
四、Java多线程和并发知识点(一)
这个系列是对《Java核心技术》中并发知识的再理解与补充。
1、进程与线程
进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位,即CPU分配时间的单位;
进程与线程的本质区别是是否单独占有内存地址及其它系统资源;
上下文切换是指CPU从一个进程(线程)切换到另一个进程(线程)。上下文是指某一时间点CPU寄存器和程序计数器的内容;
2、Thread类和Runnable接口
Thread类的构造方法是简单调用一个私有的init方法来实现初始化
g:指定线程是在哪个线程组下;
target:指定要执行的任务;
name:线程的名字,不指定会自动生成;
acc:用于初始化私有变量inheritedAccessControlContext;这个变量一般不会使用;
inheritThreadLocals:是否启动Thread类里面的两个支持ThreadLocal的私有属性;
Thread类中常用过的方法:
currentThread():静态方法,返回对当前正在执行的线程对象的引用;
start():开始执行线程的方法,java虚拟机会创建一个线程,并在这个线程第一次得到时间 片时调用run()方法;
yield():当前线程自愿让出对当前CPU的占用。需要注意,就算当前线程调用了yield()方法,程序在调度时,也还有可能继续执行这个线程;
sleep():静态方法,是当前线程睡眠一段时间,但不会释放锁标记;
join():使当前线程等待另一个线程执行完毕之后再继续执行,内部调用wait方法;
若不需要使用Thread类中的诸多方法,优先使用Runnable接口;
注:只要一个类是抽象的或者是一个接口,那么就可以使用匿名内部类来实现.。lambda表达式是匿名内部类的一种语法糖;
五、IP协议相关技术
1、DNS域名解析协议
DNS可以将域名网址自动转换为具体的IP地址。
DNS中域名是用句点来分隔的,句点代表了不同层次之间的界限。越靠右的位置表示其层级越高;
域名的层次类似于一个树状结构
根DNS服务器
顶级域DNS服务器(com)
权威DNS服务器(server.com)
根域的DNS服务器信息保存在互联网中所有的DNS服务器中,这样,任何DNS服务器就可以找到并访问根域DNS服务器了,然后再一路找到位于下层的某台目标DNS服务器。
域名解析工作流程
浏览器查看自己的缓存->操作系统的缓存->本机域名解析文件hosts->DNS服务器;
注:本地DNS服务器就是客户端TCP/IP设置中填写的DNS服务器地址;
根DNS与顶级域名服务器DNS不会进行域名解析,只是引导本地DNS去往权威DNS服务器,真正的域名解析过程在权威DNS服务器中进行;
2、ARP协议
在传输IP数据报的时候,在确定了源IP地址与目标IP地址后,就会通过路由表确定数据包的下一跳。然而网络层下面是链路层,因此我们还需要指定下一跳的MAC地址,这就需要ARP协议来解析。
主机会广播发送ARP请求,这个包中包含了想知道MAC地址的主机IP地址;
同一个链路中所有设备收到ARP请求后,拆包查看IP地址,若IP地址与自己的IP地址一致,那么这个设备就将自己的MAC地址塞入ARP响应包返回给主机;
操作系统一般会把MAC地址缓存起来,以便下次直接使用,但是有一定的期限,超过将被清除;
注:RARP协议是已知MAC地址求IP地址。需要一台RARP服务器,并且在这个服务器上注册设备的MAC地址及其IP地址,最后将这个设备接入到网络中。
3、DHCP协议
通过DHCP可以动态获取IP地址,省去了配置IP信息繁琐的过程。
DHCP客户端进程监听68端口号,DHCP服务器进程监听67端口号;
DHCP服务器通过报文可以提供客户端可租约的IP地址、子网掩码、默认网关、DNS服务器以及IP地址租用期。在租约快到期后,客户端回向服务器发送续约的报文;
可以使用DHCP中继代理,对不同网段的IP地址分配也可以由一个DHCP服务器统一进行管理;DHCP客户端会向DHCP中继代理发送DHCP请求包,而DHCP中继代理在接收这个广播包之后,再以单播的形式发送给DHCP服务器;
4、NAT协议(网络地址转换)
简单来说,NAT就是同个公司、家庭、教室内的主机对外部通信时,把私有IP地址转换为公有IP地址。
普通的NAT转换一个私有地址需要有一个公有地址对应,没有什么意义。因此可以把IP地址和端口号一起进行转换,这种转换技术就叫网络地址与端口转换NAPT。即通过NAT路由器自动生成的NAPT转换表,就可以正确的转换地址和端口的组合。两个私有IP地址都转换为公有地址,但是以不同的端口号作为区别;
NAT存在的问题
外部无法主动与NAT内部服务器建立连接;
转换表产生了性能的开销;
NAT路由重启,所有TCP连接都将被重置;
5、ICMP协议
互联网控制报文协议(ICMP),确认IP包是否成功送达目标地址、报告发送过程中IP包被废弃的原因和改善网络设置等。
ICMP大致可以分为两类:
一类是用于诊断的查询消息,也就是查询报文类型;
另一类是通知出错原因的错误信息,也就是差错报文类型;
6、IGMP协议
IGMP(因特网组管理协议)协议主要是管理组播中的分组。
IGMP报文向最后一跳的路由器申请加入和退出组播组。路由器会记录IGMP路由表,后续就会转发组播包到对应的主机;
六、Tomcat的conf目录下的web.xml文件
该文件内容相当于写入了部署在tomcat webapp文件夹下的所有项目中,是父文件;
有一个名为default的servlet,当一个请求没有相应的servlet处理时,由它来显示404;
名为jsp的servlet负责处理后缀名为.jsp或者.jspx的请求;
JAVA WEB中的mime:多用途互联网邮件扩展
当指定的拓展名文件被访问,决定浏览器是自动用指定程序打开或是下载;
application/octet-stream:下载
若是需要指定程序打开,那么就需要指定相关程序;
注:tomcat就是通过web.xml中匹配的servlet的全路径类名,再使用反射技术去生成对应类的实例化对象。反射中的class.newInstance()需要对应类对象的无参构造函数,因此对应类的无参构造函数必须存在。
七、ServletContext(一)
一个项目只有一个servletContext对象。它可以在多个servlet中传递数据。一个用户可以有多个request,一个用户一个session,所有用户只有一个ServletContext,在ServletContext中存放重要的、必要的、所有用户都需要的信息。
获取ServletContext的四种方法:
a.在servlet中获取:在init()方法中通过servletConfig.getServletContext()获取;
b.在GenericServlet或者HttpServlet中获取:GenericServlet中有getServletContext()方法,可以直接通过this.getServletContext();
c.HttpSession中也有getServletContext()方法来获取servletcontext对象;
servletContext的内容对应web.xml文件中的标签下的内容;
对应key,对应value;