JAVA笔记
文章平均质量分 77
笔记
Yawn__
“就像热爱漫无边际。”
展开
-
Java——AQS浅析
1. 概述AQS:抽象的队列式同步器Abstract Quened Synchronizer,是除了java自带的synchronized关键字之外的锁机制。简单点说:AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态符,成功则获取锁成功,失败则进入等待队列,等待被唤醒。原理:如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制原创 2021-07-01 10:21:48 · 139 阅读 · 0 评论 -
Java——方法(leetcode)
1. 数组扩充长度1://digits 为原数组 digits = new int[digits.length + 1]; digits[0] = 1; return digits;2: int[] digits1 = Arrays.copyOf(digits, digits.length+1); digits1[0] = 1; return digits12. 复制数组public static void arraycopy(Object src, int src原创 2021-06-27 14:35:00 · 319 阅读 · 0 评论 -
Java——比较器(Comparable 和 Comparator)
1. Comparable 简介Comparable 是 排序接口 。若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中原创 2021-06-18 15:56:06 · 614 阅读 · 0 评论 -
Java——集合,stack栈,Deque双端队列,优先队列
0.首先让我们大概看看集合的选择Java——集合浅析.Java—— HashMap和HashTable.Connection接口:单列集合的根接口,它表示一组对象,这些对象也称为Collection的元素Map接口:双列集合的根接口,Map集合可以存储一对对象,即会一次性保存两个对象,存在key = value 结构,其最大的特点还是可以通过key 找到对应的value 值。Connection接口: List: 有序,可重复ArrayList优点: 底层数据结构是数组,查询快,增删原创 2021-06-18 11:37:50 · 436 阅读 · 1 评论 -
Java——String、StringBuilder、StringBuffer
1. 简介共同点:String、StringBuilder、StringBuffer三者都是final类,不允许被继承的String是常量,创建后不可更改,String长度大小不可变Stringbuffer和StringBuilder长度可变StringBuffer线程安全StringBuilder线程不安全StringBuilder速度快注意:StringBuffer基本没有适用场景,有99.99%的情况下没有必要选择StringBuffer,因为StringBuffe原创 2021-06-17 10:54:49 · 170 阅读 · 0 评论 -
Java——ArrayList基本使用
1.简介ArrayList是实现List接口的,底层采用数组实现。ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。方法:2. 方法解释(1)contains(Object o)说明:判断该ArrayList中是否包含指定的内容。该方法内部调用indexOf(),如果indexOf()可以查找到该内容返回tru原创 2021-06-16 20:24:26 · 13677 阅读 · 7 评论 -
Java——原子性,可见性,有序性
1. 原子性原子性:即一个操作或者多个操作,要么全部执行,并且执行的过程不会被任何因素打断,要么就都不执行。在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。上面一句话虽然看起来简单,但是理解起来并不是那么容易。看下面一个例子:x = 10; //语句1y = x; //语句2x++; //语句3x = x + 1; //语句4注意:其实只有语句1是原子性操作,其他三个语句都不是原子性操作。语句1是直接将数值10原创 2021-05-19 15:56:31 · 6691 阅读 · 0 评论 -
Java——Synchronized/ReentrantLock
1. 引入Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突。举个例子:假设有一个卖票系统,一共有100张票,有4个窗口同时卖。public class Ticket implements Runnable { // 当前拥有的票数 private int num = 100; public void run() { while (true) { if (num > 0) { try {原创 2021-05-18 17:41:06 · 241 阅读 · 1 评论 -
Java——死锁
1. 产生条件一般来说,要出现死锁问题需要满足以下条件:互斥条件:一个资源每次只能被一个线程使用。请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。不剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。在JAVA编程中,有3种典型的死锁类型:静态的锁顺序死锁动态的锁顺序死锁协作对象之间发生的死锁。下面来一一介绍这三种死锁:2. 静态的锁顺序死锁a和b两个方法都需要获得A锁和B锁。一个线程执原创 2021-05-18 15:45:24 · 1839 阅读 · 2 评论 -
Java——浅拷贝和深拷贝
1. 引言假设,对象 A 和对象 B,都是 ClassC 的对象,具有成员变量 a 和 b,现在对对象 A 进行拷贝赋值给 B,也就是 B.a = A.a; B.b = A.b;这时再去改变 B 的属性 a 或者 b 时,可能会遇到问题:假设 a 是基础数据类型,b 是引用类型。当改变 B.a 的值时,没有问题;当改变 B.b 的值时,同时也会改变 A.b 的值,因为其实上面的例子中只是把 A.b 赋值给了 B.b,因为是 b 引用类型的,所以它们是指向同一个地址的。这可能就会给我们使用埋下隐患。转载 2021-05-17 21:03:15 · 242 阅读 · 0 评论 -
Java——NIO
1. 什么是NIOJava NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java1.4开始),Java NIO提供了与标准IO不同的IO工作方式。IO:标准的IO基于字节流和字符流进行操作的IO:传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方。NIO:NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入通道也类似。NIO:NIO操作面向缓冲区,数据从C原创 2021-05-17 20:26:46 · 79 阅读 · 0 评论 -
Java——LinkedList
1. 简介LinkedList是一个基于链表实现的简单数据结构。以双向链表实现,链表无容量限制,但双向链表本身使用了更多空间,也需要额外的链表指针操作。按下标访问元素—get(i)/set(i,e) ,遍历链表将指针移动到位(如果i>数组大小的一半,会从末尾移起)。插入、删除元素时修改前后节点的指针即可,但还是要遍历部分链表的指针才能移动到下标所指的位置,只有在链表两头的操作—add(),addFirst(),removeLast()或用iterator()上的remove()能省掉指针的移原创 2021-05-17 17:23:31 · 98 阅读 · 0 评论 -
Java——ArrayLists实现
1. 简介ArrayList是一个相对来说比较简单的数据结构,最重要的一点就是它的自动扩容,可以认为就是我们常说的“动态数组”。以数组实现,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组,默认第一次插入元素时创建大小为10的数组。按数组下标访问元素—get(i)/set(i,e) 的性能很高。直接在数组末尾加入元素—add(e)的性能也高,但如果按下标插入、删除元素—add(i,e), remove(i), remove(e),则要用System原创 2021-05-17 17:13:54 · 179 阅读 · 0 评论 -
Java——泛型
1. 简介首先,我们先来说说“语法糖”。语法糖(Syntactic Sugar)是一个专业性的术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。Java中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等。虚拟机并不支持这些语法,它们在编译阶段就被还原回了简单的基础语法结构,这个过程成为解语法糖。什么是泛型:简单来说,泛型就是一种模版泛型中的类型在使用时指定,主要用于集合中适用于多种数据类型执行相同的代码泛型类型变量不能是基本数据类原创 2021-05-17 15:44:09 · 208 阅读 · 1 评论 -
Java——注解(Annotation)
1. 简介官方解释:Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。注解的定义:通俗的来讲,注解就如同标签。一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。注解的本质就是一个继承了 Annotation 接口的接口,下面是注解 @Override 的定义,其实它本质上就是:public interface Override extends Annotation{原创 2021-05-13 19:33:26 · 121 阅读 · 1 评论 -
Java——反射机制
1.简介为什么要用反射来获取对象:new属于静态编译反射属于动态编译,只有到运行时他才会去获得该对象的实例几种获取class对象的方法:1.通过ClassLoader对象的loadClass()方法:不会对类进行初始化。 ClassLoader.getSystemClassLoader().loadClass("com.my.test.Hello")2.类名.class仅适合在编译前就已经明确要操作的 Class,同样不会对类进行初始化。 Class clazz2 = U原创 2021-05-12 20:32:01 · 1111 阅读 · 0 评论 -
Java——基础类和包装类
1. 简介当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。基本数据类型存放在栈中,效率更高每个基本类型在java.lang包中都有一个相应的包装类,new出来的对象存在于堆中(通过栈中的引用来使用这些对象),是一个对象,因此具有更多的诸如“转换”的方法例子:1.int转Integerint i = 0;Integer ii = new Integer(i);2.Inte原创 2021-05-12 17:42:16 · 192 阅读 · 0 评论 -
Java——JVM内存详解
1. 简介Java 程序运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。分配:通过关键字new创建对象分配内存空间,对象存在堆中。释放 :对象的释放是由垃圾回收机制决定和执行的JVM的内存可分为3个区:堆(heap)栈(stack)方法区(method,也叫静态区):2. 内存区域的划分一个java程序运行的数据区:首先启动一个Java虚拟机进程,这个进程首先从classpath中找到AppMain.原创 2021-05-12 17:23:51 · 4260 阅读 · 1 评论 -
Java——内存泄漏与溢出
1.浅析内存泄露( memory leak):是指程序在申请内存后,无法释放已申请的内存空间,多次内存泄露堆积后果很严重,内存迟早会被占光。内存泄漏最终会造成内存溢出。内存溢出(out of memory) :是指程序在申请内存时,没有足够的内存空间供其使用JVM中有一下几种内存空间:栈内存(Stack):每个线程私有的。堆内存(Heap):所有线程公用的。方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、编译时常量等信息。原生原创 2021-05-12 16:54:09 · 759 阅读 · 4 评论 -
Java——异常体系
1. Java异常程序运行过程中,往往会遇见各种各样的异常:文件找不到、网络连接失败、非法参数等,Java通 过API中Throwable类的众多子类描述各种不同的异常。Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的错误条件。当条件生成时,错误将引发异常。所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性Throwable有两个子类:Error(错误):是程序无法原创 2021-05-12 15:37:11 · 99 阅读 · 0 评论 -
Java——NIO和IO的区别
1. 简介NIO即New IO,JDK1.4中引入的。提供了与标准IO不同的IO工作方式,可替代 标准Java IO 的IO API。Java IO是面向流的,这意味着我们需要每次从流中读取一个或多个字节,直到读取完所有字节;NIO是面向缓冲的,也就是说会把数据读取到一个缓冲区中,然后对缓冲区中的数据进行相应处理。Java IO是阻塞IO,而NIO是非阻塞IO。阻塞IO:当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入,该线程在此期间不能再干任原创 2021-05-11 20:46:10 · 1292 阅读 · 0 评论 -
Java——foreach与for
foreach又叫增强for循环,其实就是for循环的一种简化版,以下是语法形式:for(元素类型 元素名称 : 遍历数组(集合)(或者能进行迭代的)){ 语句 }foreach主要适用于循环次数未知,或者计算循环次数比较麻烦情况下使用效率更高。更适用于访问循环链表结构的数据要注意:foreach不能对数组或集合进行修改(添加删除操作)一般较为复杂的循环还是使用for更方便一些。...原创 2021-05-11 17:51:47 · 313 阅读 · 0 评论 -
Java——线程sleep/wait
1.线程的五种状态新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。运行状态(Running): 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。阻塞状态(Blocked)原创 2021-05-11 17:42:10 · 343 阅读 · 1 评论 -
Java——ThreadPool线程池
1. 为什么使用线程池当并发执行线程数量很多时,且每个线程执行很短的时间就结束了,这样,我们频繁的创建、销毁线程就大大降低了工作效率(创建和销毁线程需要时间、资源)。java中的线程池可以达到这样的效果:一个线程执行完任务之后,继续去执行下一个任务,不被销毁,这样线程利用率提高了。假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。2. 线程池作用线程池作用就是限制系统中原创 2021-05-10 19:46:31 · 617 阅读 · 0 评论 -
Java——ThreadLocal
1 .简介ThreadLocal是一个线程的内部存储类,可以在每个线程的内部存储数据,通俗的讲:ThreadLocal也叫做线程本地变量,ThreadLoacl为变量在每个线程中的都创建了副本,每个线程可以访问自己内部的副本变量,线程之间互不影响。而是当某个很复杂的逻辑下的对象传递,需要在线程这个作用域内贯穿其中,用ThreadLocal可以避免这个创建多个静态类。它的实现原理其实比较简单,每个线程中都会维护一个ThreadLocalMap,当在某个线程中访问时,会取出这个线程自己的Map并且用当前原创 2021-05-10 17:20:59 · 86 阅读 · 0 评论 -
Java——锁浅析
1. 简介在多线程中如果涉及到对共享资源的并发读写,这时就会产生资源的争夺。而在资源争夺中,第一想到的就是使用锁 ,对共享资源进行数据保护。java中提供了2种基本也是最常用的锁:synchronized、Lock!2. 对象锁和类锁对象锁:在java中,每个对象都会有一个monitor对象,这个对象其实就是java对象锁,通常也被称作为"内置锁"或"对象锁",类的对象有多个,所有对象锁也有多个,相互之间互不干涉。类锁:在java中,针对每一个类都有一个锁,可以称作为"类锁",类锁实际也原创 2021-05-10 09:55:37 · 172 阅读 · 0 评论 -
Java——Volatile关键字
1. Volatile的语义一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。禁止进行指令重排序。先看一段代码,假如线程1先执行,线程2后执行://线程1boolean stop = false;while(!stop){ doSomething();}//线程2stop = true;这段代码是很典型的一段代码,转载 2021-05-10 09:55:24 · 131 阅读 · 0 评论 -
Java/Android——多线程详解
1. 继承Thread类创建线程类(1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。(2)创建Thread子类的实例,即创建了线程对象。(3)调用线程对象的start()方法来启动该线程。1. package com.thread; 2. 3. public class FirstThreadTest extends Thread{ 4. int i = 0; 5. //重写run方原创 2021-05-09 18:52:09 · 514 阅读 · 0 评论 -
Java——多态
多态,指的就是父类引用指向子类对象,调用方法时会调用子类的实现而不是父类的实现。多态的实现的关键在于“动态绑定”。类B是类A的子类, A a = new B() 编译时变量和运行时变量不一样,所以多态发生了① A a 作为一个引用类型数据,存储在JVM栈的本地变量表中。② new B()作为实例对象数据存储在堆中B的对象实例数据(接口、方法、field、对象类型等)的地址也存储在堆中 B的对象的类型数据(对象实例数据的地址所执行的数据)存储在方法区中,方法区中对象类型数据 中有一个指向该类方原创 2021-05-09 18:43:42 · 80 阅读 · 0 评论 -
Java——abstract 和 interface
1. 抽象(Abstract)abstract修饰类,会使该类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,需要子类继承并覆盖其中的抽象方法。一个类继承了一个抽象类,必须实现抽象类里面所有的抽象方法,否则,此类也是抽象类。public abstract class Person { public Person() { System.out.println("Person抽象类,也有构造方法"); } /** * 抽象方法原创 2021-05-09 00:01:08 · 147 阅读 · 0 评论 -
Java——Static class
比较静态对象非静态对象拥有属性:是类共同拥有的是类各对象独立拥有的内存分配:内存空间上是固定的空间在各个附属类里面分配分配顺序:先分配静态对象的空间继而再对非静态对象分配空间,也就是初始化顺序是先静态再非静态.Java静态对象到底有什么好处?静态对象的数据在全局是唯一的,一改都改。如果你想要处理的东西是整个程序中唯一的,弄成静态是个好方法。 非静态的东西你修改以后只是修改了他自己的数据,但是不会影响其他同类对象的数据。引用方便。直接用 类名.静态方法...原创 2021-05-09 00:00:55 · 170 阅读 · 0 评论 -
Java——重写与重载
1. 重写(Override)重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。即外壳不变,重写内在实现!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。 在面向对象原则里,重写意味着可以重写任何现有方法。实例如下:class Animal{ public void move(){ System.out.println("Animal can move"); }}class Pig转载 2021-05-09 00:00:48 · 90 阅读 · 0 评论 -
Java——回调
1. 回调的分类(1)同步调用同步调用是最基本并且最简单的一种调用方式,类A的方法a()调用类B的方法b(),一直等待b()方法执行完毕,a()方法继续往下走。这种调用方式适用于方法b()执行时间不长的情况,因为b()方法执行时间一长或者直接阻塞的话,a()方法的余下代码是无法执行下去的,这样会造成整个流程的阻塞。(2)异步调用异步调用是为了解决同步调用可能出现阻塞,导致整个流程卡住而产生的一种调用方式。类A的方法方法a()通过新起线程的方式调用类B的方法b(),代码接着直接往下执行,这样无论原创 2021-05-09 00:00:40 · 150 阅读 · 0 评论 -
Java——SOF 与 OOM
1. SOF (堆栈溢出 StackOverflow)StackOverflowError 的定义: 当应用程序递归太深而发生堆栈溢出时,抛出该错误。因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。栈溢出的原因:递归调用大量循环或死循环全局变量是否过多数组、List、map数据过大2. Android的OOM(Out Of Memory)当内存占有量超过了虚拟机的分配的最大值时就会产生内存溢出(VM里面分配不出更多的page原创 2021-05-09 00:00:24 · 742 阅读 · 0 评论 -
Java——Collection集合
1. Collection 单列集合List 元素是有序的、可重复有序的 collection,可以对列表中每个元素的插入位置进行精确地控制。可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。可存放重复元素,元素存取是有序的。List接口中常用类:Vector:线程安全,但速度慢,已被ArrayList替代。底层数据结构是数组结构ArrayList:线程不安全,查询速度快。底层数据结构是数组结构LinkedList:线程不安全。增删速度快。底层数据结构是列表结原创 2021-05-08 11:53:48 · 73 阅读 · 0 评论 -
Java—— HashMap和HashTable
1、历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。2、也许最重要的不同是Hashtable的方法是同步的,但是这也是HashTable效率低下的原因,任何方法都是同步的,而HashMap的方法不是。这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多线程的应用程序中用一个Hashtable,但你必须同样地为一个HashMap提供外同步。一个方便的方法就是利用Collections类的静态的synchronizedMap原创 2021-05-08 11:30:53 · 495 阅读 · 3 评论 -
Java——集合浅析
Map<K, V>: Java中存储键值对的数据类型都实现了这个接口,表示“映射表”。支持的两个核心操作是get(Object key)以及put(K key, V value),分别用来获取键对应的值以及向映射表中插入键值对。Set: 实现了这个接口的集合类型中不允许存在重复的元素,代表数学意义上的“集合”。它所支持的核心操作有add(E e),remove(Object o), contains(Object o),分别用于添加元素,删除元素以及判断给定元素是否存在于集中。-List.原创 2021-05-08 11:20:32 · 221 阅读 · 0 评论 -
Java——String、StringBuffer与StringBuilder的区别。
1. 浅析String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全)String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象。所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,原创 2021-05-08 11:04:53 · 93 阅读 · 0 评论 -
Java——hashcode的作用
hashCode用于返回对象的散列值,用于在散列函数中确定放置的桶的位置。hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违原创 2021-05-08 10:47:39 · 356 阅读 · 0 评论 -
JVM——四种引用(强软弱虚)
1.强引用(StrongReference)强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。如下:Object O=new Object(); // 强引用当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。如果不使用时,要通过如下方式来弱化引用,如下:o=null; // 帮助垃圾收集器回收此对象显式地设置O为null,或超出对象的生命周期范围,则gc认为转载 2021-05-08 10:43:07 · 242 阅读 · 0 评论