
java基础部分
java基础部分
miller.zc
记录和分享一些工作和学习中的笔记
展开
-
多线程执行任务,取结果归集
开启线程池并需要获取结果归集的情况下,如何实现,以及优劣,下面是任务执行完,结果归集时,几种方式:一.ExecutorService+Futrue原理:Future接口封装了取消,获取线程结果,以及状态判断是否取消,是否完成这几个方法demo:使用线程池提交Callable接口任务,返回Future接口,添加进list,最后遍历FutureList且内部使用while轮询,并发获取结果(1)、创建线程池ExecutorService exs = Executors.newFixedThrea原创 2020-12-22 14:23:13 · 1885 阅读 · 0 评论 -
Callable、Future和FutureTask
一、Callable与Runnable区别Runnable:无返回值,不会抛出异常Callable:有返回值,并会抛出异常。二、Future对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。通过get方法获取执行结果,该方法会阻塞直到任务返回结果。boolean cancel(boolean mayInterruptIfRunning);取消任务,mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务原创 2020-12-22 14:08:28 · 261 阅读 · 0 评论 -
线程辅助类CountDownLatch、CyclicBarrier和Semaphore
一.CountDownLatch用法1、作用: 类似于一个倒数计时器,一个线程的执行,要等这个计时器归零的时候再执行, 就可以用这个工具类。2、用法:(1)、通过构造方法,构造出这个计数器final CountDownLatch latch = new CountDownLatch(2);(2)、在需要倒数计时才执行的线程代码中设置阻塞等待latch.await();(3)、在其它线程逻辑中对计数器进行倒数递减latch.countDown();(4)、当count为0的时候,原创 2020-12-22 14:07:24 · 139 阅读 · 0 评论 -
阻塞队列和线程池
一、阻塞队列(1)、用处:如果不用阻塞队列,那么对于容器的添加和删除元素,就需要手动去实现同步锁,防止元素为空时再取数据,元素满了再加数据的情况发送。阻塞队列相当于封装了这一种同步逻辑。·(2)、几种主要的阻塞队列 ArrayBlockingQueue: 基于数组,必须指定容量大小,默认为非公平的队列, 即等待时间最长的任务不一定能先执行。 LinkedBlockingQueue: 基于链表实现,也就是不用指定容器大小,默认大小为Integer.MAX_VAL原创 2020-12-22 14:06:02 · 334 阅读 · 0 评论 -
同步容器
一.为什么会出现同步容器?像ArrayList、LinkedList、HashMap这些容器都是非线程安全的。如果有多个线程并发地访问这些容器时,就会出现线程安全问题。因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。二、Java中的同步容器类(1)、Vector、Stack、HashTable(2)、Collections类中提供的静态工厂方法创建的类 Vector实现了List接口,Vector实际上就是一个数组原创 2020-12-22 14:02:54 · 195 阅读 · 1 评论 -
volatile和ThreadLocal
一.深入剖析volatile关键字1、volatile关键字的两层语义:(1)、保证了不同线程对这个共享变量进行操作时的可见性,即一个线程修改了该变量的值, 这新值对其他线程来说是立即可见的(马上刷新到主内存,其它线程里面原来的副本立即失效, 并马上重新从主内存读取)。(2)、禁止进行指令重排序,也就是volatile修饰的变量,编译后, 和它的前后代码的顺序不会发送改变。2、volatile不能保证原子性比如自增操作,会分为3步:1、读取主内存数据到线程内存,生成一个线原创 2020-12-22 14:01:08 · 657 阅读 · 0 评论 -
JVM锁
一、synchronized关键字1、synchronized的本质本质上就是在代码块或者方法执行的首尾行添加了两条指令:monitorenter和monitorexitmonitorenter:对象的锁计数加1monitorexit:对象的锁计数减1每个对象的都对应一个监视器锁(monitor)对象,当monitor被占用(大于1)时就会处于锁定状态,其它线程不能访问。在获取对象锁的时候(获取cpu执行权的时候),就调用monitorenter,对象锁加1,此时锁大于0,则其他线程不原创 2020-12-22 14:00:43 · 154 阅读 · 0 评论 -
jvm线程安全问题
一、什么时候会出现线程安全问题?1、JMM模型:多线程对一个共享的资源进行修改(非原子性操作)的时候,由于每个线程对应不同的线程内存,而JMM(java内存模型)是分为主内存和线程内存的,就会造成线程安全问题(一个线程在线程内存里面已经修改了,但是没有刷新到主内存,另外一个线程从主内存读取的还是未修改过的原值)比如:线程A从主内存读取共享变量为0,存到线程内存后再自增+1,在自增加1之后,还没有把自增后的变量刷新到主内存此时线程B获得cup执行权,从主内存读取到的数据还是为1,这时候就出现原创 2020-12-21 10:29:53 · 297 阅读 · 0 评论 -
线程概念
一、如何创建线程(1)、继承Thread类重写run方法,在run方法中定义需要执行的任务。创建好了这个继承Thread类的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。(2)、实现Runnable接口重写Runnable接口的run方法,在run方法中定义需要执行的任务。创建好了这个实现Runnable接口的类之后,new出实例runnable,传入到Thread类的构造方法中(Thread thread = new Thread(runnable));然后通原创 2020-12-21 10:02:17 · 126 阅读 · 0 评论 -
JVM GC
一、怎样判断对象是否已经死亡(1)、引用计数法对象头里面有一个计数,当有一个栈中的变量指向这个对象,计数就加1。当栈中的变量销毁,不再指向这个对象,计数就减1。当对象头里面的计数为0时,就标记为可回收对象。这样的方法m不能解决循环引用的问题,如果一个对象A持有对象B,而对象B也持有一个对象A,A与B的counter恒大于1,会使得GC永远无法回收这两个对象。(2)、可达性分析法 从堆中的对象向上查找,一直到GC root(栈变量\静态变量、静态常量等方法区或栈中的数据) 没有任何关系链原创 2020-12-21 10:01:29 · 112 阅读 · 0 评论 -
类的加载机制
一、什么是类的加载源文件编译之后,会生成.class文件,jvm将.class文件加载进内存,.class里面的描述信息(类名/方法/静态变量/常量等),会存入方法区,然后会在堆内存里面生成一个对应的java.lang.Class对象。这个java.lang.Class对象就是对方法区里面.class文件信息的封装,可以通过这个对象获取方法区中存的信息。二、类的生命周期(1)、加载:将.class文件的信息存入方法区,在堆中生成java.lang.Class对象。(2)、连接阶段:原创 2020-12-21 10:01:00 · 478 阅读 · 0 评论 -
JVM内存结构
一、概念(1)、jvm在运行时,会将它管理的内存区域分为堆、栈、方法区、程序计数器等区域,(2)、堆(head)和方法区是线程共享的,是存储数据的区域,解决的是数据存储的问题, 即数据怎么放、放在哪儿。(3)、栈(stack)和程序计数器是线程私有的,是运行时的区域,解决程序的运行问题, 如何处理数据。二、分别的作用:(1)、堆(head)是所有线程共享的区域。堆是jvm管理的内存中最大的一块,用来存放对象,总体分为老年代和新生代,其中新生代又分为三个部分,eden原创 2020-12-21 10:00:34 · 250 阅读 · 0 评论 -
动态代理
一、动态代理概念通过JDK动态代理或cglib在运行中动态生成代理对象,而不需要在编译的时候实现代理对象。不需要自己写代理类。分为两种:1、JDK动态代理:对应静态代理模式的聚合方式,是通过注入目标类、代理类和目标类实现同一个接口,重写同一个方法来实现代理逻辑的。2、cglib动态代理:对应静态代理的继承方式,是通过继承目标类,重写目标类方法,通过super关键字调用目标类方法来实现代理逻辑的。二、JDK动态代理详解1、目标类必须实现一个接口public class RealS原创 2020-12-20 12:32:43 · 208 阅读 · 1 评论 -
静态代理
一、静态代理概念代理模式:目标对象类型的变量指向代理对象,然后调用方法的时候会执行代理对象的方法,代理对象的方法里面重写或者调用了目标对象的方法,并且在方法执行前后添加了一些功能。静态代理:写好对应的代理类源文件,在编译期就已经确定了目标类和代理类。分为两种:(1)、继承方式:代理类继承目标类,然后再代理类里面重写目标类的方法,在重写的方法里面,通过super.的方式调用目标类的方法(父类方法),在调用前后做一些其它的处理。public class CarProxy extends原创 2020-12-20 12:28:45 · 1019 阅读 · 2 评论 -
内部类详解
一.内部类基础1.成员内部类 (1)、相当于外部类的一个属性,在编译之后,会自动带上外部类的引用 (2)、成员内部类里面可以随意访问外部类的属性和方法(私有的也可以) (3)、外部类要访问内部类,就必须使用new的形式,new出内部类实例之后再进行访问。 (4)、在其他类里面要访问内部类,要先new出外部类,再new出内部类 因为内部类的构造函数里面需要用到外部类的引用,内部类是依赖于外部类的。 (5)、创建内部类的方式: //第一种方式:原创 2020-12-20 12:26:04 · 173 阅读 · 1 评论 -
回顾Java基础——HashMap
一、 HashMap介绍HashMap简介HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。HashMap 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量原创 2020-05-18 17:45:04 · 176 阅读 · 0 评论 -
回顾Java基础——二叉树和红黑树
二叉树二叉树是树的特殊一种,具有如下特点:1、每个结点最多有两颗子树,结点的度最大为2。2、左子树和右子树是有顺序的,次序不能颠倒。3、即使某结点只有一个子树,也要区分左右子树。一、特殊的二叉树及特点1、斜树所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。这就是斜树,应用较少2、满二叉树所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树。就是完美圆满的意思,关键在于树的平衡。根据满二叉树的定义,得到其特点为:叶子只能出现在最下一层。非原创 2020-05-18 17:13:31 · 501 阅读 · 0 评论 -
回顾Java基础——栈和队列详解
一、概述栈跟队列都是保存数据的容器。还有前面的线性表。栈和队列主要用于计算过程中保存的临时数据,如果数据在编程时就可以确定,那么使用几个变量就可以临时存储,但是如果存储的数据项数不能确定,就需要复杂的存储机制。这样的存储机制称为缓存。栈和队列就是使用最多的缓存结构。1、栈、队列和数据使用顺序栈和队列是最简单的缓存结构,它们只支持数据项的存储和访问,不支持数据项之间的任何关系。因此,它们最重要的两个操作就是存入元素和取出元素。当然还有其他的操作,比如创建,检查空(或者满)的操作。按照数据在时原创 2020-05-18 16:54:50 · 1052 阅读 · 0 评论 -
回顾Java基础——ArrayList和LinkedList
一、ArrayList和linkedList的区别ArrayArray(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大,因为这需要重排数组中的所有数据, (因为删除数据以后, 需要把后面所有的数据前移)缺点: 数组初始化必须指定初始化的长度, 否则报错例如: int[] a = new int[4];//推介使用int[] 这种方式初始化 int c[] = {23,43,56原创 2020-05-18 16:44:02 · 294 阅读 · 0 评论 -
回顾Java基础——注解详解
一、概述跟踪代码的依赖性,实现代替配置文件的功能。比较常见的是Spring等框架中的基于注解配置。登陆、权限拦截、日志处理,以及各种Java框架,如Spring,Hibernate,JUnit 。提到注解就不能不说反射,Java自定义注解是通过运行时靠反射获取注解。实际开发中,例如我们要获取某个方法的调用日志,可以通过AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。如Hibernate,Jersey,Spring。注解相当于是一种嵌入在程原创 2020-05-09 15:42:59 · 190 阅读 · 0 评论 -
回顾Java基础——枚举详解
原始的接口定义常量public interface IConstants { String MON = "Mon"; String TUE = "Tue"; String WED = "Wed"; String THU = "Thu"; String FRI = "Fri"; String SAT = "Sat"; String SUN = "Sun";}语法(定义)创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.la原创 2020-05-09 15:35:31 · 291 阅读 · 0 评论 -
回顾Java基础——反射详解
一.通过一个对象获得完整的包名和类名 方法:class.getClass().getName()。二.实例化Class类对象 有三种方法: 1.推荐此种方式进行构建类:Class.forName("className"); 2.java的任何一个java对象都有getClass方法; 3.每个类都有class属性:className.class。三.通过Class实例化其他类的对象通过无参构造实例化对象:Class cls = Class.forName("原创 2020-05-09 15:25:47 · 213 阅读 · 0 评论 -
回顾Java基础——泛型详解
**1 泛型介绍**1.1 泛型的出现 泛型的出现还得从集合说起,没有泛型的时候,我们将一个对象存入集合时, 集合不care这个对象的数据类型是什么,当我们再次从这个对象取出来的时候, 对象的编译类型会变成Object类型,这时候我们就需要强制类型转换, 但是这种行为每次都要去指定类型进行强制转换,并且有可能强制转换不了, 比如我存的是Integer类型,误转换为String类型,那就可能会引发ClassCastException异常。 当Java 5引入了一个叫做“参数化类型原创 2020-05-09 15:12:57 · 182 阅读 · 0 评论 -
回顾Java基础——final关键字
一、概念:final可以修饰变量,方法和类final修饰过的变量不可变,修饰过的方法不可重写,修饰过的类不可继承。1、变量成员变量可以分为类变量(static修饰的变量)以及实例变量类变量: 必须要在静态初始化块中指定初始值或者声明该类变量时指定初始值, 而且只能在这两个地方之一进行指定;成员变量: 除了类变量的两个地方之外,还可以在构造器中指定初始值。局部变量:...原创 2020-04-30 18:01:39 · 147 阅读 · 0 评论 -
回顾Java基础——深入理解java类实例化顺序
一、Java虚拟机类加载机制1、jvm将java源文件被编译成class文件,然后将class文件加载到内存,并对数据进行校验、解析、初始化,最终形成可以被虚拟机直接使用的java类型。这就是虚拟机的类加载机制。2、类的生命周期如下:<1>、加载: 根据全类名获取class文件的二进制流。 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。 在内存中...原创 2020-04-30 17:53:49 · 174 阅读 · 0 评论 -
回顾Java基础——String深入分析
一、概念:1、String不是基本数据类型,String和8种包装类型是不可变类。 String和8种基本数据类型采用值传递。2、静态常量池(class文件的常量池)存储:常量池要保存的是已确定的字面量值(比如:String s = "xxx",new String("xxx"))如果在字符串拼接中,有一个参数是非字面量,而是一个变量的话,整个拼接操作会被编译成String...原创 2020-04-30 14:14:09 · 149 阅读 · 0 评论 -
回顾Java基础——OOP三大特性详解
一、继承的概念(1)、子类继承父类,子类拥有父类的方法和属性(只要是访问符不为private).(2)、继承只能是单继承,一个类只有一个父类,但是可以通过内部类继承其 他类来实现多继承。(3)、方法的重写: 子类重新父类的方法,当调用方法时会优先调用子类的方法。(4)、方法重载: 在同一个类中,除了方法名相同,其它的都可以不同。 重写和重载的区别: ...原创 2020-04-30 14:00:22 · 591 阅读 · 0 评论 -
关于java线程安全和一些"锁"事
一、为什么并发编程的时候需要"锁"?对于一些共享的数据,多个线程并发访问,如果不用锁,可能会造成数据错乱。为了在并发的情况下保持这些共享数据的一致性,所以必须加锁。二、java锁的核心理论(1)、共享性...原创 2020-01-26 23:11:13 · 188 阅读 · 0 评论 -
关于反射\自定义注解\泛型的理解
一、反射(1)、什么是反射?我的理解就是:在程序运行过程中,可以得到Class对象的属性、方法,说白了就是获取Class对象的所有信息。(2)、为啥用反射? 既然上面都说了,可以获取到Class对象的所有信息,那么就肯定能对获取到的方法或者属性做一些操作。 这对于我们封装一些通用的方法是很有帮助的, 你想想,你传个参数(类对象,比如Person.Class),然后在通用方法里面得到这...原创 2020-01-23 10:00:46 · 469 阅读 · 1 评论 -
Java基础回顾(为什么要配置JDK)
一、JDK配置环境变量详细解释(1) 需要配置三个变量 (PATH,CLASSPATH,JAVA_HOME)后,JDK才能使用(2) 环境变量说白了就是一个变量(和Java里面的变量差不多,是一个指向)(3) JAVA_HOME环境变量:指向jdk的安装目录,可以是JAVA_HOME=“D:\jdk1.8”。因为每个人jdk的安装目录不一样,所以我们必须要指定一个变量(4) Path环境变...原创 2019-03-31 15:06:53 · 684 阅读 · 0 评论 -
Maven配置
1、概念:本地仓库和远程仓库: 仓库就是存放依赖和插件的地方, 本地仓库: 就是Maven在本地储存构件的地方,maven本地仓库的默认位置:.m2/repository/ 远程仓库: 最核心的中央仓库开始,中央仓库是默认的远程仓库,maven在安装的时候,自带的就是中央仓库的配置 <repositories> <repositor...原创 2019-03-31 15:09:06 · 127 阅读 · 0 评论 -
Maven项目在部署到Tomcat之后,各种资源请求路径理解分析(彻底搞懂javaweb项目路径问题)
一、项目结构当这个项目部署到tomcat上后,结构会变成这样理解:如果是eclipse,部署之后项目会出现在tomcat的webapps目录下如果是idea,部署之后项目会出现在设置的out目录下我们会发现,项目部署到tomcat之后,工程目录里面的(1)java和(2)resources文件夹看不到了,那么去哪里了呢?我们点开WEB-INF为文件夹:lib文件夹里面是项目的j...原创 2019-08-22 16:58:49 · 4869 阅读 · 1 评论 -
关于多线程
一、什么情况下适合用多线程(1)、计算量大,可以分段计算的情况。(2)、分段计算或者执行,没有依赖关系的情况。二、多线程的实现: (1)、一般来说,很少使用原生的new thread(继承Runnable的对象)来执行多线程任务,因为这种方式 第一,没有用到线程池,不利于线程管理, 第二,Runnable没有返回值和异常处理,拿不到最终的结果,也发现不了异常情况。...原创 2019-10-26 00:56:57 · 156 阅读 · 0 评论