JavaSE基础补充+JVM学习复习总结记录

写在前面:
新开了一门外教课程,Object-oriented Programming(JAVA),学习了JavaSE基础相关内容,部分内容课程中没有讲到故自己找了一些其他资料进行补充。
Object-oriented Programming(JAVA)的结课project见文章SMAC。
Reference:

  1. Object-oriented Programming(Java) ----天津大学Marc
  2. Java高级编程 ---- 阿里云开发者学院
  3. B站首发:JVM类加载、JDK、内存模型、GC垃圾回收全系知识点

1. JavaSE基础进阶

1.1 多线程

  1. Thread类继承
  2. Runnable接口实现
    (利用Runnable描述多个线程操作的资源,而Thread描述每一个线程对象)
  3. Callable接口实现
    (Callable在JDK1.5之后提出的,Callable重写的call()方法可以有返回值,Runnable重写的run()方法无返回值)
  4. 多线程常用操作方法
// 线程休眠
Thread.sleep() (加trycatch处理异常)


//线程中断
 Thread thread = new Thread(()->{
 // ......
 });
 // ......
thread.interrupt();
 // ......


// 线程强制执行(获取强制执行对象之后才可以执行join的调用)
Thread mainThread = Thread.currentThread();
 // ......
mainThread.join();
 // ......

// 线程礼让(每一次调用yield()方法都只会礼让一次当前的资源)
Thread.yield();

// 线程可以设置优先级
// 代码略,道理一样,文档中带static用类调用,普通方法需实例化后调用
  1. synchronized(与pthread_mutex_lock一个效果),可以配合wait()和notify()使用

  2. 优雅停止线程:不用.stop的方式(强停容易造成错误),在线程里加一个boolean的flag

  3. 守护线程:.setDaemon(true)。(在JVM中,最大的守护线程是GC线程)(和linux守护进程概念一个意思)

  4. volatile关键字:不使用副本,直接操作原始变量(直接操作这块内存),相当于节约了拷贝副本,重新放回的步骤。(主要在attribute上使用)
    在正常进行变量处理三个步骤:

  • 获取变量原有数据内容副本;
  • 利用副本为变量进行数学计算;
  • 将计算后的变量,保存到原始空间之中;
  1. ThreadLocal类,并发情况下用(同步问题),保存了线程对象名字和数据对象,使得不会对同一数据对象覆写。每一个线程通过ThreadLocal只允许保存一个数据(多线程资源引用传递)

1.2 反射

< ? extends T >:上界通配符(频繁读取)
< ? super T >:下界通配符(频繁插入)

// Class类对象的三种实例化模式
// 1.
Person per = new Person();
Class<? extends Person> cls = per.getClass();
cls.getName(); 
// 2.
Class<? extends Person> cls = Person.class;
cls.getName(); 
// 3.
// 不用import包(只需要个字符串)
Class<?> cls = Class.forName("projetc.a.Person");
cls.getName();
// 通过newInstance()方法实例化类对象(等价关键字new)(只需要个字符串)
Class<?> cls = Class.forName("projetc.a.Person");
Object obj = cls.getDeclaredConstructor().newInstance();

当获取了一个类的Class对象之后,就意味着这个对象可以获取类中的一切继承结构信息、获取调用构造函数(有参无参)、获取调用普通方法(invoke())、获取成员属性(getType())

反射机制最大特征是可以根据其自身的特点(Object类直接操作)实现相同功能类的重复操作的抽象处理。(用字符串来实现类属性的set)。反射也可以实现动态代理设计模式,绑定不同的接口/类。

反射也可以获取Annotation信息,也可以利用Annotation属性配置接口/类。

1.3 集合&泛型

(泛型与C++模版用法相似,集合与C++STL 用法相似)
类集框架核心接口:Collection、List、Set、Map、Iterator、Enumeration、Queue、ListIterator

  1. Comparable比较器(c++仿函数)
    在Arrays数组中,除了Integer, String等类可以直接用Arrays.sort(),自定义的类需要用比较器处理,自定义的类实现Comparable<>比较器,覆写compareTo()方法。(List用Collections.sort())
    Comparator
    挽救的比较操作。再定义一个类并实现Comparator接口,覆写compare方法。在Arrays.sort(data, new DataComparator)用这个类。

  2. ArrayList(implements RandomAccess)(c++Vector):底层实现是数组在这里插入图片描述
    JDK1.9以后,无参构造不开辟空间,add以后开辟默认(10)大小空间,之后超过了的话,需要复制拷贝操作,然后开辟空间成倍增长。
    Plus. Vector无参构造上来开辟10个空间,且其他操作与ArrayList一样。Vector线程安全,但性能不如ArrayList高。

  3. LinkedList(无RandomAccess):底层实现是双向链表
    用iterator迭代输出(用get效率低)

(ArrayList 类和 LinkedList 类都是不同步的,不保证线程安全。)

  1. Vector
    Vector 类和 ArrayList 类的方法基本是相同的,主要区别是 Vector 类的所有方法都是同步的,因此可以保证线程安全

  2. HashSet/TreeSet之前文章。TreeSet的一个interesting point, 若是自定义类,需实现Compareable接口,并且每种属性都要进行比较。

  3. 集合输出:
    Iterator迭代输出(不同于 Iterator 类型的迭代器只支持单向遍历,ListIterator 类型的迭代器支持双向遍历。
    Enumeration为Vector服务

  4. HashMap/HashTable/TreeMap/LinkedHashMap/ConcurrentHashMap
    Map的一个interesting point, 若是自定义类型的Key,Key类型所在的类中一定要覆写hashCode()和equals()方法,但一般不这样用。

  5. Collections工具类操作Collection (有点#include < alogorithm >的意思)

  6. Iterable 接口:Iterable 接口从 JDK 1.5 开始出现,是 Java 容器的最顶级的接口之一,该接口的作用是使容器具备迭代元素的功能。Collection 接口继承了 Iterable 接口。

1.4 网络编程

// TCP
package project
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

// 服务端关键代码(需要Runnable多线程包装)
ServerSocket server = new ServerSocket(9999);
Socket client = server.accept();
// 客户端输入流
Scanner scan = new Scanner(client.getInputStream());
// 客户端输出流
PrintWriter out = new PrintWriter(client.getOutputStream());

// 客户端关键代码
Socket client = new Socket("localhost", 9999);
Scanner scan = new Scanner(client.getInputStream());
PrintStream out = new PrintStream (client.getOutputStream());

// UDP
// 服务端关键代码
DatagramSocket server = new DatagramSocket(9999);
DatagramPacket packet = new DatagramPacket(数据地址端口);
server.send(packet);

// 客户端关键代码
DatagramSocket client = new DatagramSocket(9999);
byte data[] = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
client.receive(packet);

2. JVM

2.1 内存模型

在这里插入图片描述

  1. 栈:栈中有栈帧
  2. 程序计数器:程序计数器在多线程时可记录执行到哪行代码
  3. 本地方法栈(native)(调c/c++)
  4. 方法区:常量,静态变量,类元信息

堆内存分代模型
在这里插入图片描述

2.2 类加载机制

(复习)c/c++的编译执行过程
预处理阶段(预处理器cpp):处理以 # 开头的预处理命令;
编译阶段(编译器):翻译成汇编文件;
汇编阶段(汇编器):将汇编文件翻译成可重定向目标文件(二进制);
链接阶段(链接器):将可重定向目标文件和 printf.o 等单独预编译好的目标文件进行合并,得到最终的可执行目标文件。

java类加载
在这里插入图片描述

类加载器及双亲委派机制
在这里插入图片描述
引导类加载器:JAVA_HOME/lib
扩展类加载器:JAVA_HOME/lib/ext
应用类加载器:classpath

在这里插入图片描述
Tomcat可以部署多个服务/war包,打破了双亲委派机制。双亲委派机制,当目前的类加载器加载过,会立即返回;但如果没有加载过,不会立即加载,而是向上委托,当到了引导类加载器时,发现没加载过,会在jre/lib下的核心类库中找,如果没有,则向下扔(后边省略)。

自定义类加载器,重写loadClass()方法,破坏双亲委派机制

2.3 GC垃圾回收机制

1.识别垃圾对象:

  • 引用计数法:多个变量指向同一个对象,在对象上记数(Java没有采取,解决不了互相引用的问题)
  • 可达性分析算法:
    在这里插入图片描述

2.垃圾回收算法:

  • Mark-Sweep(标记清除):位置不连续,产生碎片
  • Copying(复制):没有碎片,浪费空间,因为一半一半切的
  • Mark-Compact(标记整理):没有碎片,效率偏低

年轻代一开始Minor GC,老年代也满了触发Full GC,GC会造成STW(stop the word)停下用户线程来GC

3.常用垃圾收集器:
在这里插入图片描述
左边6个垃圾收集器:

JDK初期默认:
Serial串行,用户线程停止,单线程GC;
Parallel并行,用户线程停止,多线程GC;

JDK1.8及之前默认:
ParNew在Parallel上改造,配合CMS,原理也是需要暂停用户线程;
CMS(ConcurrentMarkSweep)解决stop the word时间过长问题。初始标记时间快,因为只是标记GC roots,并发标记寻找其他垃圾,重新标记解决两种情况(1.之前没标,运行时变成垃圾的浮动垃圾标记。2.之前标了,后来不是垃圾了,也需要重新标记)
注意,CMS采取标记清除算法,会造成碎片,并行处理可能出现异常,为了解决,CMS 的GC与Serial Old GC配合使用
在这里插入图片描述

  • 对于垃圾收集器来说,新生代往往采取复制算法,老年代往往采取标记整理算法(CMS采取标记清除算法)

右边垃圾收集器:
分区模型(不是分代模型)
JDK1.9默认:G1

其他

String:不可变
StringBuffer:可变,线程安全(并发)
StringBuilder:可变,线程不安全(迭代)
String的compareTo()方法,先比ASCII码直到第一个不相同,若全相同之后才比长度

charSequence接口描述字符串
AutoCloseable接口关闭各种资源(必须配合try catch)

Runtime类可获取操作系统资源信息(单例设计,只能get一个,个人理解是该类在描述这个JVM进程)(gc手工处理,用Runtime.getRuntime().gc())

Stream数据流类对大数据进行一些操作分析时可用
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值