「底层容器java」容器底层实现

博主:adminadmin 2023-03-21 11:04:06 593

本篇文章给大家谈谈底层容器java,以及容器底层实现对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Java哪些容器是底层容器

1.ArrayList(非线程安全的)

底层的数据结构其实就是数组,但是它比数组优秀的地方在于他是动态的,即不必像数组那样固定大小,那么他是如何实现这种数据结构是数组,但是给我们看起来确实不固定大小的呢?

ArrayList 是通过将底层 Object 数组复制的方式(System.arraycopy方法)来处理数组的增长;

当ArrayList 的容量不足时,其扩充容量的方式:先将容量扩充至当前容量的1.5倍,若还不够,则将容量扩充至当前需要的数量。

所以由上面可以看出ArrayList用于查找的话就相当于数组十分快,但是如果是插入或者删除的话则十分慢。

2.LinkedList(非线程安全)

顾名思义底层的数据结构是链表,而且是双向链表,所以他也具有链表的特点,即插入或者删除的话很快,但是如果是查找的话则比较缓慢。

3.HashSet(非线程安全)

底层数据结构是散列表(关于散列表看下面),仅仅存储对象(而hashMap是存储键值对),突出特点是存的对象不可重复,保证这一点是通过先对比每个对象的hashCode,如果hashCode相同,再对比equal()来确定两个对象是否重复,所以放入hashset的对象一定要重写hashCode()和equal().

4.HsahMap(非线程安全)

底层也是散列表(见下面),通过键值对来存储数据,通过键来获取值,速度比hashset快,键和值可以null.

5.LinkedHashMap

继承自HashMap,只不过在HashMap哈希表的数据结构基础上,又在每个entry里面记录上一个和下一个的引用,所以他有记录每个item顺序的功能(与hashmap相比),所以他实际上是哈希表加双向链表的一种数据结构。LruCache里面就是用的就是linkedhashmap来实现的。

现在介绍一下散列表(哈希表)这种数据结构:

首先每个对象产生一个哈希值(因为哈希值太大,数组不可能开这么大,会造成巨大浪费),所以需要通过一个哈希函数对哈希值进行转化,如图1000就转化为0,,3013就放入3,这样访问对象就跟数组一样便捷,插入对象也十分便捷,如果是碰到哈希值转化后是同一值得,即产生冲突,则像上面这种解决冲突的方式就是 链表的方式,哈希值在数组里同一位置的都用链表链接起来。所以散列表实际上是查找快,插入删除也快,解决了数组和链表各自的一些缺点。

简述一下Java中的web容器,举几个例子也行

目前市场上常用的开源Java Web容器有Tomcat、Resin和Jetty。其中Resin从V3.0后需要购买才能用于商业目的,而其他两种则是纯开源的。可以分别从他们的网站上下载最新的二进制包和源代码。

作为Web容器,需要承受较高的访问量,能够同时响应不同用户的请求,能够在恶劣环境下保持较高的稳定性和健壮性。在HTTP服务器领域,Apache HTTPD的效率是最高的,也是最为稳定的,但它只能处理静态页面的请求,如果需要支持动态页面请求,则必须安装相应的插件,比如mod_perl可以处理Perl脚本,mod_python可以处理Python脚本。

上面介绍的三中Web容器,都是使用Java编写的HTTP服务器,当然他们都可以嵌到Apache中使用,也可以独立使用。分析它们处理客户请求的方法有助于了解Java多线程和线程池的实现方法,为设计强大的多线程服务器打好基础。

Tomcat是使用最广的Java Web容器,功能强大,可扩展性强。最新版本的Tomcat(5.5.17)为了提高响应速度和效率,使用了Apache Portable Runtime(APR)作为最底层,使用了APR中包含Socket、缓冲池等多种技术,性能也提高了。APR也是Apache HTTPD的最底层。可想而知,同属于ASF(Apache Software Foundation)中的成员,互补互用的情况还是很多的,虽然使用了不同的开发语言。

Tomcat 的线程池位于tomcat-util.jar文件中,包含了两种线程池方案。方案一:使用APR的Pool技术,使用了JNI;方案二:使用Java实现的ThreadPool。这里介绍的是第二种。如果想了解APR的Pool技术,可以查看APR的源代码。

ThreadPool默认创建了5个线程,保存在一个200维的线程数组中,创建时就启动了这些线程,当然在没有请求时,它们都处理“等待”状态(其实就是一个while循环,不停的等待notify)。如果有请求时,空闲线程会被唤醒执行用户的请求。

具体的请求过程是: 服务启动时,创建一个一维线程数组(maxThread=200个),并创建空闲线程(minSpareThreads=5个)随时等待用户请求。 当有用户请求时,调用 threadpool.runIt(ThreadPoolRunnable)方法,将一个需要执行的实例传给ThreadPool中。其中用户需要执行的实例必须实现ThreadPoolRunnable接口。 ThreadPool首先查找空闲的线程,如果有则用它运行要执行ThreadPoolRunnable;如果没有空闲线程并且没有超过maxThreads,就一次性创建minSpareThreads个空闲线程;如果已经超过了maxThreads了,就等待空闲线程了。总之,要找到空闲的线程,以便用它执行实例。找到后,将该线程从线程数组中移走。 接着唤醒已经找到的空闲线程,用它运行执行实例(ThreadPoolRunnable)。 运行完ThreadPoolRunnable后,就将该线程重新放到线程数组中,作为空闲线程供后续使用。

由此可以看出,Tomcat的线程池实现是比较简单的,ThreadPool.java也只有840行代码。用一个一维数组保存空闲的线程,每次以一个较小步伐(5个)创建空闲线程并放到线程池中。使用时从数组中移走空闲的线程,用完后,再“归还”给线程池。

Java 数组与容器类的区别

容器类和数组,整体没啥区别,归根结底都是为了编程计算算法等需要出现的数据结构

所以说容器类和数组本质一样 存储数据的方式不一样,数组的存储方式是固定的,就是在初始化的时候数组有多少个元素就是固定的,而且类型必须是一致,比如里面是int类型,里面存放的元素全是int类型,不能有其他的类型。

而数组又是最常用的数据结构 所以几乎所有高级语言都可以直接定义数组

而java的容器类 ArrayList 底层结构也是数组 但是他大小可变,可以存放不同类型的值,里面也有泛型,不止ArrayList,还有Set ,Map等等,方式都差不多。都是可变的。

底层容器java的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于容器底层实现、底层容器java的信息别忘了在本站进行查找喔。