
Java核心编程技术
文章平均质量分 94
本专栏主要对Java基础、集合与多线程进行剖析!巩固基础,提高技术(阅读顺序:从下往上,受欢迎的文章会置顶)
张维鹏
这个作者很懒,什么都没留下…
展开
-
Java基础篇:反射机制详解
一、什么是反射: 反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期知道运行的对象是谁,他允许运行中的Java程序获取类的信息,并且可以操作类或对象内部属性。程序中对象的类型一般都是在编译期就确定下来的,而当我们的程序在运行时,可能需要动态的加载一些...原创 2019-12-03 23:50:42 · 218654 阅读 · 72 评论 -
Java基础篇:什么是hashCode 以及 hashCode()与equals()的联系
1、什么是hashCode:hashCode就是对象的散列码,是根据对象的某些信息推导出的一个整数值,默认情况下表示是对象的存储地址。通过散列码,可以提高检索的效率,主要用于在散列存储结构中快速确定对象的存储地址,如Hashtable、hashMap中。为什么说hashcode可以提高检索效率呢?我们先看一个例子,如果想判断一个集合是否包含某个对象,最简单的做法是怎样的呢?逐一取出集合中的每个元素与要查找的对象进行比较,当发现该元素与要查找的对象进行equals()比较的结果为true时,则停止继续原创 2018-10-19 19:39:44 · 63938 阅读 · 24 评论 -
Java集合篇:HashMap 与 ConcurrentHashMap 原理总结
一、HashMap原理总结:1、什么是HashMap:(1)HashMap 是基于 Map 接口的非同步实现,线程不安全,是为了快速存取而设计的;它采用 key-value 键值对的形式存放元素(并封装成 Node 对象),允许使用 null 键和 null 值,但只允许存在一个键为 null,并且存放在 Node[0] 的位置,不过允许存在多个 value 为 null 的情况。(2)在 JDK7 及之前的版本,HashMap 的数据结构可以看成“数组+链表”,在 JDK8 及之后的版本,原创 2021-08-16 08:57:59 · 35734 阅读 · 21 评论 -
Java IO篇:什么是 Proactor 网络模型?
Proactor 是异步网络模式, 感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址(用来存放结果数据)等信息,这样系统内核才可以自动帮我们把数据的读写工作完成,这里的读写工作全程由操作系统来做,并不需要像 Reactor 那样还需要应用进程主动发起 read/write 来读写数据,操作系统完成读写工作后,就会通知应用进程直接处理数据。原创 2022-01-10 08:15:00 · 6696 阅读 · 0 评论 -
Java IO篇:什么是 Reactor 网络模型?
Reactor 模式也叫做反应器设计模式,是一种为处理服务请求并发提交到一个或者多个服务处理器的事件设计模式。当请求抵达后,通过服务处理器将这些请求采用多路分离的方式分发给相应的请求处理器。Reactor 模式主要由 Reactor 和处理器 Handler 这两个核心部分组成,它俩负责的事情如下:① Reactor:负责监听和分发事件,事件类型包含连接事件、读写事件;② Handler :负责处理事件,如 read -> 业务逻辑 (decode + compute + encode)-> send原创 2022-01-24 02:01:28 · 18962 阅读 · 3 评论 -
Java IO篇:什么是零拷贝?
在传统的数据 IO 模式中,读取一个磁盘文件,并发送到远程端的服务,就共有四次用户空间与内核空间的上下文切换,四次数据复制,分别是两次 CPU 数据复制,两次 DMA 数据复制。零拷贝指在进行数据 IO 或传输时,数据在用户态下经历了零次拷贝,并非不拷贝数据。通过减少数据传输过程中 内核缓冲区和用户进程缓冲区间不必要的 CPU数据拷贝 与 用户态和内核态的上下文切换次数,降低 CPU 在这两方面的开销,释放 CPU 执行其他任务,更有效的利用系统资源,提高传输效率,同时还减少了内存的占用,提升应用程序的性能原创 2022-01-24 08:15:00 · 17676 阅读 · 5 评论 -
Java IO篇:序列化与反序列化
两个服务之间要传输一个数据对象,就需要将对象转换成二进制流,通过网络传输到对方服务,再转换成对象,供服务方法调用。这个编码和解码的过程称之为序列化和反序列化。所以序列化就是把 Java 对象变成二进制形式,本质上就是一个byte[]数组。将对象序列化之后,就可以写入磁盘进行保存或者通过网络中输出给远程服务了。反之,反序列化可以从网络或者磁盘中读取的字节数组,反序列化成对象,在程序中使用。原创 2022-01-12 08:30:00 · 12193 阅读 · 1 评论 -
JUC多线程:阻塞队列ArrayBlockingQueue与LinkedBlockingQueue
阻塞队列最大的特性在于支持阻塞添加和阻塞删除方法:(1)阻塞添加:当阻塞队列已满时,队列会阻塞加入元素的线程,直到队列元素不满时才重新唤醒线程执行加入元素操作。(2)阻塞删除:但阻塞队列元素为空时,删除队列元素的线程将被阻塞,直到队列不为空再执行删除操作原创 2021-10-11 09:45:00 · 9801 阅读 · 0 评论 -
JUC多线程:Atomic原子类与CAS原理
tomic 原子操作类是基于无锁 CAS + volatile 实现的,并且类中的所有方法都使用 final 修饰,进一步保证线程安全。而 CAS 算法的具体实现方式在于 Unsafe 类中,Unsafe 类的所有方法都是 native 修饰的,也就是说所有方法都是直接调用操作系统底层资源进行执行相应任务。Atomic 使用乐观策略,每次操作时都假设没有冲突发生,并采用 volatile 配合 CAS 去修改内存中的变量,如果失败则重试,直到成功为止。原创 2021-10-11 09:45:00 · 9434 阅读 · 0 评论 -
JUC多线程:ThreadLocal 原理总结
ThreadLocal 提供了线程内部的局部变量,当在多线程环境中使用 ThreadLocal 维护变量时,会为每个线程生成该变量的副本,每个线程只操作自己线程中的变量副本,不同线程间的数据相互隔离、互不影响,从而保证了线程的安全。ThreadLocal 内存泄露的根本原因在于 ThreadLocalMap 的生命周期与当前线程 CurrentThread 的生命周期相同,且 ThreadLocal 使用完没有进行手动删除导致的原创 2021-10-11 09:30:00 · 10961 阅读 · 1 评论 -
JUC多线程:CountDownLatch、CyclicBarrier、Semaphore同步器原理总结
1、CountDownLatch,闭锁,主要作用是使一个或一组线程在其他线程执行完毕之前,一直处于等待状态,直到其他线程执行完成后再继续执行。2、CyclicBarrier,循环栅栏,通过 CyclicBarrier 可以实现一组线程之间的相互等待,当所有线程都到达屏障点之后再执行后续的操作。3、Semaphore 信号量,主要用于控制并发访问共享资源的线程数量,依赖 AQS 的变量 state 作为许可证 permit,通过控制许可证的数量,来保证线程之间的配合。原创 2021-10-11 09:15:00 · 11105 阅读 · 0 评论 -
JUC多线程:AQS抽象队列同步器原理
AQS,Abstract Queued Synchronizer,抽象队列同步器,是 J.U.C 中实现锁及同步组件的基础。工作原理就是如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就将获取不到锁的线程加入到等待队列中。这时,就需要一套线程阻塞等待以及被唤醒时的锁分配机制,而 AQS 是通过 CLH 队列实现锁分配的机制。原创 2021-10-11 09:00:00 · 9372 阅读 · 0 评论 -
JUC多线程:synchronized锁机制原理 与 Lock锁机制
synchronized 通过当前线程持有对象锁,从而拥有访问权限,而其他没有持有当前对象锁的线程无法拥有访问权限,保证在同一时刻,只有一个线程可以执行某个方法或者某个代码块,从而保证线程安全。synchronized 锁机制在 Java 虚拟机中的同步是基于进入和退出监视器锁对象 monitor 实现的原创 2021-08-26 08:55:35 · 15671 阅读 · 11 评论 -
JUC多线程:JMM内存模型与volatile内存语义
JMM 是 Java 虚拟机定义的一种多线程访问 Java 内存各个变量的访问规范,主要围绕如何解决并发过程中的原子性、可见性、有序性这三个问题来解决线程的安全问题。Java 内存模型将内存分为了主内存和工作内存。主内存存放所有的共享变量,所有线程都可以访问。每个线程都有自己的工作内存,存储了该线程使用到的变量的副本,线程对变量的所有操作都必须在自己的工作内存中完成,不能直接操作主存中的变量。操作时,首先将变量从主内存拷贝到自己的工作内存中,然后在自己的工作内存中对变量进行操作,操作完成后再将变量写回主存原创 2021-10-09 11:47:01 · 4346 阅读 · 12 评论 -
JUC多线程:线程的中断停止
对于线程的停止,通常情况下我们是不会去手动去停止的,而是等待线程自然运行至结束,但在实际开发中,很多情况中需要我们提前去手动来停止线程,比如程序中出现异常错误、使用者关闭程序等情况中。如果不能很好地停止线程那么可能会导致各种问题,所以正确的停止线程是非常的重要的,常见的中断线程的方式有以下几种:① 方式一:使用 Thread 类的 stop() 方法来终止线程;② 方式二:根据 volatile 修饰的标志位判断线程是否需要中断;③ 方式三:通过 interrupt中断机制终止线程;原创 2022-01-24 08:00:00 · 3789 阅读 · 2 评论 -
JUC多线程:线程池的创建及工作原理 和 Executor 框架
一、什么是线程池:线程池主要是为了解决 新任务执行时,应用程序为任务创建一个新线程 以及 任务执行完毕时,销毁线程所带来的开销。通过线程池,可以在项目初始化时就创建一个线程集合,然后在需要执行新任务时重用这些线程而不是每次都新建一个线程,一旦任务已经完成了,线程回到线程池中并等待下一次分配任务。二、创建线程池:1、通过Executors创建线程池:在JUC包中的Executors中,提供了一些静态方法,用于快速创建线程池,常见的线程池有:(1)newSingleThreadExecutor:创建一原创 2020-11-01 02:33:36 · 12934 阅读 · 0 评论 -
JUC多线程:创建线程的四种方式
Java多线程的实现方式主要有四种:(1)继承Thread类,重写run();(2)实现Runnable接口,重写run();(3)实现Callable接口,实现call() 方法,通过FutureTask包装器来创建Thread线程;(4)使用ExecutorService、Callable、Future实现有返回结果的多线程。原创 2019-01-18 02:06:30 · 16247 阅读 · 0 评论 -
JUC多线程:系统调用、进程、线程的上下文切换
1、上下文切换就是一个线程释放处理器的使用权,另外一个线程获取处理器的使用权的过程;在切入切出时,系统会保存和读取当前线程的上下文信息,用户恢复线程的执行进度;自发和非自发的调用操作,都会导致上下文切换,会导致系统资源开销。2、在 JDK 的 java.lang.Thread.State 源码中定义了6个状态,在某一时刻,一个线程只能处于一种状态:New、Runnable、Blocked、Waiting、Timed Waiting、Terminated原创 2021-10-24 08:00:00 · 8384 阅读 · 1 评论 -
ArrayList与LinkedList、Vector的区别 && HashMap与HashTable、HashSet的区别
一、ArrayList和LinkedList区别 二、ArrayList和Vector的区别 三、HashMap和Hashtable的区别 四、HashMap和HashSet的区别原创 2018-06-25 16:25:52 · 7868 阅读 · 0 评论 -
Java集合篇:fail-fast机制 与 fail-safe
在JDK的Collection中我们时常会看到类似于这样的话:例如,ArrayList:注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检...转载 2018-10-25 23:03:09 · 2799 阅读 · 0 评论 -
Java集合篇:HashSet
对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素。HashSet存储元素的顺序并不是按照存入时的顺序,是按照哈希值来存的,所以取数据也是按照哈希值来取得。HashSet集合元素不能是Null。一、定义:public class HashSet<E> extends AbstractSet<E> impl...转载 2018-10-18 23:36:44 · 2195 阅读 · 0 评论 -
Java集合篇:Map总结
相关阅读:Java基础篇:hashCode的作用Java集合篇:HashMap原理详解(JDK1.7及之前的版本)Java集合篇:HashMap原理详解(JDK1.8)Java集合篇:Hashtable原理详解 、Hashtable与HashMap的区别Java集合篇:ConcurrentHashMap详解(JDK1.6)Java集合篇:ConcurrentHashMap详...转载 2018-10-25 21:48:01 · 1424 阅读 · 0 评论 -
Java集合篇:Map常用遍历方式 以及 性能对比
一、Map集合常用的遍历方式:遍历Map集合的常用方式有三种:使用keySet的方式,使用entrySet的方式,使用values()取值的方式,这三种方式中,都有对应的for循环遍历和Iterator遍历的方式取值。具体用法如下:public class MapTest { public static void main(String[] args) { HashMap&l...原创 2018-10-12 14:54:09 · 5364 阅读 · 3 评论 -
Java集合篇:Hashtable原理详解(JDK1.8)
(本文使用的源码基于JDK1.8的) 一、Hashtable的基本方法:这部分参考博客:https://blog.youkuaiyun.com/chenssy/article/details/228968711、定义:HashTable在Java中的定义如下:public class Hashtable<K,V> extends Dictionary<K,V...原创 2018-10-19 17:07:09 · 3490 阅读 · 1 评论 -
Java集合篇:ConcurrentHashMap详解(JDK1.8)
(本文使用的源码都是基于JDK1.8的)(基于JDK1.6的版本可以参考这篇文章:https://blog.youkuaiyun.com/a745233700/article/details/83120464)ConcurrentHashMap是conccurrent家族中的一个类,由于它可以高效地支持并发操作,以及被广泛使用,经典的开源框架Spring的底层数据结构就是使用ConcurrentHas...转载 2018-10-18 04:02:06 · 3764 阅读 · 0 评论 -
Java集合篇:ConcurrentHashMap详解(JDK1.6)
(本文有关ConcurrentHashMap的源码都是基于JDK1.6的)(基于JDK1.8的版本可以参考这篇文章:https://blog.youkuaiyun.com/a745233700/article/details/83123359)摘要: ConcurrentHashMap是J.U.C(java.util.concurrent包)的重要成员,它是HashMap的一个线程安全的、支持高...转载 2018-10-18 03:26:55 · 6093 阅读 · 0 评论 -
Java集合篇:HashMap原理详解(JDK1.8)
概述JDK 1.8对HashMap进行了比较大的优化,底层实现由之前的“数组+链表”改为“数组+链表+红黑树”,本文就HashMap的几个常用的重要方法和JDK 1.8之前的死循环问题展开学习讨论。JDK 1.8的HashMap的数据结构如下图所示,当链表节点较少时仍然是以链表存在,当链表节点较多时(大于8)会转为红黑树。 几个点:先了解以下几个点,有利于更好的理解HashMa...转载 2018-12-20 17:16:09 · 2891 阅读 · 0 评论 -
Java集合篇:HashMap原理详解(JDK1.7及之前的版本)
(本文有关HashMap的源码都是基于JDK1.6的)摘要: HashMap是Map族中最为常用的一种,也是 Java Collection Framework 的重要成员。本文首先给出了 HashMap 的实质并概述了其与 Map、HashSet 的关系,紧接着给出了 HashMap 在 JDK 中的定义,并结合源码分析了其四种构造方式。最后,通过对 HashMap 的数据结构、实现原...转载 2018-10-17 14:55:31 · 2114 阅读 · 0 评论 -
Java集合篇:List总结
相关阅读:Java集合篇:ArrayList详解Java集合篇:LinkedList源码分析Java集合篇:VectorJava集合篇:Stack 一、List接口概述:List接口,称为有序的Collection,也就是序列,该接口可以对列表中的每一个元素的插入位置进行精准的控制,同时用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。下面是Li...转载 2018-10-25 17:53:15 · 1313 阅读 · 0 评论 -
Java集合篇:集合细节:为集合指定初始容量、asList的缺陷、subList的缺陷
一、为集合指定初始容量:集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许)。当这个海、容器的量变得非常大的时候,它的初始容量就会显得很重要了,因为挖海、扩容是需要消耗大量的人力物力财力的。同样的道理,Collection的初始容量也显得异常重要。所以:对于已知的情景,请为集合指定初始容量。public...转载 2018-10-25 23:41:38 · 1114 阅读 · 0 评论 -
Java集合篇:Stack
在Java中Stack类表示后进先出(LIFO)的对象堆栈。栈是一种非常常见的数据结构,它采用典型的先进后出的操作方式完成的。每一个栈都包含一个栈顶,每次出栈是将栈顶的数据取出,如下: Stack通过五个操作对Vector进行扩展,允许将向量视为堆栈。这个五个操作如下:操作 操作 empty() 测试堆栈是否为空。 peek() 查看堆栈顶部的对象,但不从堆栈...转载 2018-10-21 14:11:31 · 3707 阅读 · 0 评论 -
Java集合篇:Vector
一、Vector简介:(1)Vector可以实现可增长的对象数组。与数组一样,可以使用整数索引进行访问的组件。不过,Vector的大小是可以增加或者减小的,以便适应创建Vector后进行添加或者删除操作。(2)同时Vector是线程安全的!底层使用的是synchronized进行加锁。public class Vector<E> extends AbstractL...转载 2018-10-20 23:03:45 · 3345 阅读 · 0 评论 -
Java集合篇:LinkedList源码分析
(注:本文内容基于JDK1.6)一、概述:LinkedList与ArrayList一样实现List接口,只是ArrayList是List接口的大小可变数组的实现,LinkedList是List接口链表的实现。基于链表实现的方式使得LinkedList在插入和删除时更优于ArrayList,而随机访问则比ArrayList逊色些。LinkedList实现所有可选的列表操作,并允许所有的元...转载 2018-10-14 18:44:18 · 985 阅读 · 0 评论 -
Java集合篇:ArrayList详解
一、ArrayList概述:ArrayList是实现了List接口的动态数组,所谓动态数组就是他的大小是可变的。实现了所有可选列表操作,并允许包括Null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大小。默认初始容量是10。默认初始容量为10。随着ArrayLis...转载 2018-10-25 16:51:15 · 18329 阅读 · 1 评论 -
Java集合篇:集合类介绍
上面的图展示了整个集合大家族的成员以及他们之间的关系。下面就上面的各个接口、基类做一些简单的介绍(主要介绍各个集合的特点,区别)。一、Collection接口:llection接口是最基本的集合接口,它不提供直接的实现,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。Collection所代表的是一种规则,它所包含的元素都必须遵循一条或者多条规则。...原创 2018-10-13 00:34:45 · 2615 阅读 · 0 评论 -
Java基础篇:数组
数组是一种线性数据结构,是一个使用连续的内存空间存放相同的数据类型的集合容器,与其他容器相比,数组的区别主要在于性能与保存基本类型的能力。在Java中,数组是一种效率最高的存储和随机访问对象的方式,通过寻址公式,随机访问的时间复杂可以达到O(1),但是为了保持空间的连续性,在数组中插入、删除数据时,都需要移动后面数据,该操作的时间复杂度为O(n)。另外,由于空间上连续,所以数组对CPU缓存比较友好,借助CPU的缓存机制,预读数组中的数据,提高访问效率。但是,由于数组是定长原创 2018-10-10 16:10:12 · 38786 阅读 · 4 评论 -
Java基础篇:Iterator迭代器
一、什么是Iterator:迭代器(Iterator)是一个对象,它的工作是遍历并目标序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素的方法,把访问逻辑从不同类型的集合类中抽象出来,又不必暴露该对象内部细节。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器的遍历。由于创建迭代器的代价小,因此迭代器通常被称为轻量级的容器。常常使用JDK提供的迭代接口...原创 2018-10-21 13:47:57 · 9200 阅读 · 1 评论 -
Java基础篇:异常机制
目录:一、为什么使用异常:二、异常体系:三、异常的捕捉--try、catch、finally:四、关于异常的题:五、自定义异常:六、异常链:七、异常的使用误区:八:throw、throws:九:异常使用指南总结:一、为什么使用异常:异常的处理机制可以确保我们程序的健壮性,提高系统可用率。在我们的程序设计当中,任何时候任何地方都有可能会出现异常,在没有异常...原创 2018-10-07 23:04:56 · 1804 阅读 · 1 评论 -
Java基础篇:泛型与类型擦除
一、什么是泛型;泛型的本质是 参数化类型,也就是说 将所操作的数据类型 指定为一个参数,在不创建新的类型的情况下,通过泛型指定的不同类型,来控制形参具体限制的类型。类似于方法中的变量参数,此时类型也定义成参数形式,然后在使用的过程中,指定具体的类型。这种参数类型可以在类、接口、方法中使用,分别称为泛型类、泛型接口、泛型方法。二、泛型的好处:没有泛型的情况的下,通过对类型Obj...原创 2018-09-27 19:14:42 · 14261 阅读 · 0 评论 -
Java基础篇:equals()方法与==的区别
目录:一、equals()方法与 “=="号 的区别:1、超类Object的equals()底层原理:2、equals()与"==" 的区别:3、equals()的重写规则:4、有关equals()与 == 号的小例子:二、equals()与hashCode()方法:1、认识HashCode()方法:2、equals()与hashCode()的联系:3、hash...原创 2018-10-06 23:03:54 · 6136 阅读 · 10 评论