JDK学习.md
文章目录
目录
这里记录一下Java语言的新特性,以版本号区分。
介绍一些注解,一些注意Java语言的注意事项。
第二章-多线程
KLT和ULT
线程是调度CPU的最小单元,也叫轻量级进程LWP (Light Weight Process)
两种线程模型:
内核级线程KLT(Kemel-Level Threads)
- 线程管理的所有工作(创建和撤销)由操作系统内核完成
- 操作系统内核提供一个应用程序设计接口API,供开发者使用KLT
纯内核级线程特点:
进程中的一个线程被阻塞,内核能调度同一进程的其他线程(就绪态)占有处理器运行 多处理器环境中,内核能同时调度同一进程的多线程,将这些线程映射到不同的处理器核心上,提高进程的执行效率。 应用程序线程在用户态运行,线程调度和管理在内核实现。线程调度时,控制权从一个线程改变到另一线程,需要模式切换,系统开销较大。
用户级线程ULT(User-Level Threads ULT)
线程切换不需要内核模式,能节省模式切换开销和内核资源。 允许进程按照特定的需要选择不同的调度算法来调度线程。调度算法需要自己实现。 由于其不需要内核进行支持,所以可以跨OS运行。 不能利用多核处理器有点,OS调度进程,每个进程仅有一个ULT能执行,一个ULT阻塞,将导致整个进程的阻塞。
简单区分:
用户线程(ULT):用户程序实现,不依赖操作系统核心,应用提供创建、同步、调度和管理线程的函数来控制用户线 程。不需要用户态/核心态切换,速度快。内核对ULT无感知,线程阻塞则进程(包括它的所有线程)阻塞。
内核线程(KLT):系统内核管理线程(KLT),内核保存线程的状态和上下文信息,线程阳塞不会引起进程阻塞。在多 处理器系统上,多线程在多处理器上并行运行。线程的创建、调度和管理由内核完成,效率比ULT要慢,比进程操 作快。
一句话区分,一个App若线程交给操作系统管理就是内核级线程KLT,若是交给APP自己管理就是用户级线程ULT。
线程池
Executors类可以创建各种线程池。
|
|
常用线程池讲解
new ThreadPoolExecutor();
有五个参数:
-
corePoolSize:核心线程数量
-
maximumPoolSize:线程池最大容量
-
keepAliveTime:非核心线程存活时间
-
TimeUnit:时间单位 (second /sek(ə)nd/ 秒)
-
BlockingQueue:阻塞队列,一旦线程池用完,任务讲进入阻塞队列。
在任意时刻,不管并发有多高,永远只有一个线程能够进行队列的入队或者出队操作! 线程安全的队列。
当队列满了,所有入队的操作都必须等待,也就是被阻塞。
当队列空了,所有出队的操作都必须等待,也就是被阻塞。
-
RejectedExecutionHandler 拒绝策略,可选参数,默认为AbortPolicy,队列满了之后再有任务,就会抛异常。
poo.shutdown()和shutdownNow()区别
- shutdown()不再接受新的任务,而是把原来任务执行完.
- shutdownNow()不再接受新的任务,队列任务也不再执行,当前执行任务执行到安全点退出。
|
|
线程池五种状态
Running 能接受新任务以及处理己添加的任务 Shutdown 不接受新任务,可以处理已经添加的任务 Stop 不接受新任务,不处理已经添加的任务,并且中断正在处理的任务 Tidying 所有的任务已经终止,ct1记录的”任务数量”为0,ctl负责记录线程池的运行状态与活动线程数量 Termi nated 线程池彻底终止,则线程池转变为terminated状态
定时任务
TimerTask
|
|
ScheduledExecutorService
|
|
第三章-JDK8新特性
1接口默认方法
|
|
2Lambda
(参数) -> (lambda操作符) 一行代码可以直接写在()中 多行在()中加{}
|
|
每一个lambda表达式都对应一个类型,通常是接口类型,而“函数式接口”是指仅仅只包含一个抽象方法的接口
3::语法
类名::方法名
|
|
4Stream流
流(Stream) 到底是什么呢? 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。 “集合讲的是数据,流讲的是计算!”
生成
- stream() − 为集合创建串行流。
- parallelStream() − 为集合创建并行流。
|
|
5函数接口
|
|
6日期时间类
Date/Calendar
1Date 2Calendar
一Date类(历史悠久) 月份与小时从0开始,天数从1开始,年从1900开始
Date()的构造函数,仅有两个推荐使用。
- Date():生成一个代表当前日期时间的 Date 对象。该构造器在底层调用 System.currentTimeMillis() 获得 long 整数作为日期参数。
- Date(long date):根据指定的 long 型整数来生成一个 Date 对象。该构造器的参数表示创建的 Date 对象和 GMT 1970 年 1 月 1 日 00:00:00 之间的时间差,以毫秒作为计时单位。
|
|
**二.Calendar类 ** ==月最大为11==
①抽象类
②不能直接实例化
Calendar和Date都是表示日期的工具类,可以直接自由转换。
|
|
Calendar 类提供了大量访问、修改日期时间的方法,常用方法如下。
- void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
- int get(int field):返回指定日历字段的值。
- int getActualMaximum(int field):返回指定日历字段可能拥有的最大值。例如月,最大值为11。
- int getActualMinimum(int field):返回指定日历字段可能拥有的最小值。例如月,最小值为0。
- void roll(int field, int amount):与 add() 方法类似,区别在于加上 amount 后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。
- void set(int field, int value):将给定的日历字段设置为给定值。
- void set(int year, int month,int day):设置 Calendar 对象的年、月、日三个字段的值。
- void set(int year, int month,int day, int hourOfDay, int minute, int second):设置 Calendar 对象的年、月、日、时、分、秒6个字段的值。
上面的很多方法都需要一个 int 类型的 field 参数,field 是 Calendar 类的类变量,如 Calendar.YEAR、Calendar.MONTH 等分别代表了年、月、日、小时、分钟、秒等时间字段。需要指出的是,Calendar.MONTH 字段代表月份,月份的起始值不是1,而是0,所以要设置8月时,用7而不是8。如下程序示范了Calendar 类的常规用法。
|
|
add和roll区别
add(int field, int amount) 的功能非常强大,add 主要用于改变 Calendar 的特定字段的值。如果需要增加某字段的值,则让 amount 为正数;如果需要减少某字段的值,则让 amount 为负数即可。
当被修改的字段超出它允许的范围时,会发生进位,即上一级字段也会增大。
1 2 3 4 5 6 7 8 9 10 11
Calendar cal1 = Calendar.getInstance(); cal1.set(2003, 7, 23, 0, 0, 0); // 2003-8-23 cal1.add(MONTH, 6); // 2003-8-23 => 2004-2-23 System.out.println(cal1.getTime()); //若下一字段也需要改变,也会改变 Calendar cal2 = Calendar.getInstance(); cal2.set(2003, 7, 31, 0, 0, 0); // 2003-8-31 // 因为进位到后月份改为2月,2月没有31日,自动变成29日 cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29 System.out.println(cal2.getTime());
==roll不会改变其它字段==
容错性:cal.setLenient(false);默认Calendar是容错的,使用这个代码可以把容错性关闭。这样设置月份为13时就会报错。
日期时间包
Java 8 开始专门新增了一个 java.time 包,该包下包含了如下常用的类。
-
Clock:该类用于获取指定时区的当前日期、时间。该类可取代 System 类的 currentTimeMillis() 方法,而且提供了更多方法来获取当前日期、时间。该类提供了大量静态方法来获取 Clock 对象。
-
Duration:该类代表持续时间。该类可以非常方便地获取一段时间。
-
Instant:代表一个具体的时刻,可以精确到纳秒。该类提供了静态的 now() 方法来获取当前时刻,也提供了静态的 now(Clock ck) 方法来获取 clock 对应的时刻。除此之外,它还提供了一系列 minusXxx() 方法在当前时刻基础上减去一段时间,也提供了 plusXxx() 方法在当前时刻基础上加上一段时间。
-
LocalDate:该类代表不带时区的日期,例如 2007-12-03。该类提供了静态的 now() 方法来获取当前日期,也提供了静态的 now(Clock clock) 方法来获取 clock 对应的日期:除此之外,它还提供了 minusXxx() 方法在当前年份基础上减去几年、几月、几周或几日等,也提供了 plusXxx() 方法在当前年份基础上加上几年、几月、几周或几日等。==年月天正常==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
LocalDate localDate = LocalDate.now(); LocalTime localTime = LocalTime.now(); LocalDateTime localDateTime = LocalDateTime.now(); System.out.println("localDate="+localDate); //localDate=2019-09-16 System.out.println("localTime="+localTime); //localTime=10:11:01.625851400 System.out.println("localDateTime="+localDateTime); //localDateTime=2019-09-16T10:11:01.625851400 System.out.println("localDate="+localDate.getDayOfWeek().getValue()); //获取星期几 System.out.println("localDate="+localDate.get(ChronoField.ALIGNED_WEEK_OF_MONTH)); //获取当前月的第几周 System.out.println(localDate.getDayOfYear()); //获取本年中截止到今天已经过去的天数 System.out.println(localDate.with(TemporalAdjusters.firstDayOfMonth())); //得到所在月的第一天 System.out.println(localDate.withDayOfMonth(2)); //得到所在月的第二天 System.out.println(localDate.with(TemporalAdjusters.lastDayOfMonth())); //得到所在月的最后一天 System.out.println(localDate.plusDays(20)); //得到20天后的日期
-
LocalTime:该类代表不带时区的时间,例如 10:15:30。该类提供了静态的 now() 方法来获取当前时间,也提供了静态的 now(Clock clock) 方法来获取 clock 对应的时间。除此之外,它还提供了 minusXxx() 方法在当前年份基础上减去几小时、几分、几秒等,也提供了 plusXxx() 方法在当前年份基础上加上几小时、几分、几秒等。
-
LocalDateTime:该类代表不带时区的日期、时间,例如2007-12-03T10:15:30。该类提供了静态的 now() 方法来获取当前日期、时间,也提供了静态的 now(Clock ck) 方法来获取 clock 对应的日期、时间。除此之外,它还提供了 minusXxx() 方法在当前年份基础上减去几年、几月、几日、几小时、几分、几秒等,也提供了 plusXxx() 方法在当前年份基础上加上几年、几月、几日、几小时、几分、几秒等。
-
MonthDay:该类仅代表月日,例如–04-12。该类提供了静态的 now() 方法来获取当前月日,也提供了静态的 now(Clock ck) 方法来获取 clock 对应的月日。
-
Year:该类仅代表年,例如2014。该类提供了静态的 now() 方法来获取当前年份,也提供了静态的 now(Clock clock) 方法来获取 clock 对应的年份。除此之外,它还提供了 minusYears() 方法在当前年份基础上减去几年,也提供了 plusYears() 方法在当前年份基础上加上几年。
-
YearMonth:该类仅代表年月,例如2014-04。该类提供了静态的 now() 方法来获取当前年月,也提供了静态的 now(Clock ck) 方法来获取 clock 对应的年月。除此之外,它还提供了 minusXxx() 方法在当前年月基础上减去几年、几月,也提供了 plusXxx() 方法在当前年月基础上加上几年、几月。
-
1 2 3 4 5
//以字符串构建YearMonth对象 YearMonth yearMonth=YearMonth.parse("2020-12") //其月份为1-12 ,在使用其构建Canlendar和Date时 //注意月份-1
-
-
ZonedDateTime:该类代表一个时区化的日期、时间。
-
ZoneId:该类代表一个时区。
-
DayOfWeek:这是一个枚举类,定义了周日到周六的枚举值。
-
Month:这也是一个枚举类,定义了一月到十二月的枚举值。
|
|
第四章-其它
给方法加删除线
可以在方法前加@Deprecated表示这个方法过时,即将删除。
abstract interface
如果有人问你为什么有abstract interface 修饰类,答案一定是他看到的这种方式一定是反编译出来的结果。 实际中abstract interface和interface修饰的类没有区别。 接口是特殊的抽象类。
1反射
反射获得类对象的三种方法
1 2 3 4 5
//反射获得类对象 方式1 Class classBook = Class.forName("com.lsl.entity.Books"); //反射获得类对象 方式2、3 Class<? extends Books> aClass = books.getClass(); Class<Books> booksClass = Books.class;
利用获得的反射的对象:
1 2 3 4 5 6 7
//1可以创建对象 Books books= (Books) classBook.newInstance(); //2获得这个类的方法,字段(私有也可以), //方法名称,参数.class Method setBookID = classBook.getMethod("setBookID", Integer.class); setBookID.invoke(books,25);//要执行方法的对象,实参
还可以获得反射的字段。Constructor类
1 2 3
//构造方法、也可以传构造方法参数的class Constructor<? extends Books> constructor = aClass.getConstructor(); //创建对象也是使用newInstance();
2泛型
https://www.cnblogs.com/coprince/p/8603492.html
泛型类,是在实例化类的时候指明泛型的具体类型;
泛型方法,是在调用方法的时候指明泛型的具体类型 。
?是一种类型实参,可以看做为Number等所有类的父类
|
|
泛型中方法的返回
@param tClass 传入的泛型实参
- @return T 返回值为T类型
- 说明:
- 1)public 与 返回值中间
非常重要,可以理解为声明此方法为泛型方法。 - 2)只有声明了
的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。 - 3)
表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。 - 4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
1 2 3 4
//这里虽然用到了泛型,但并不是泛型方法 public T getKey(){ return key; }
|
|
3自定义注解
https://blog.csdn.net/zt15732625878/article/details/100061528
JDK中有一些元注解,主要有@Target,@Retention,@Document,@Inherited用来修饰注解。
@Target 表明该注解可以应用的java元素类型
Target类型 | 描述 |
---|---|
ElementType.TYPE | 应用于类、接口(包括注解类型)、枚举 |
ElementType.FIELD | 应用于属性(包括枚举中的常量) |
ElementType.METHOD | 应用于方法 |
ElementType.PARAMETER | 应用于方法的形参 |
ElementType.CONSTRUCTOR | 应用于构造函数 |
ElementType.LOCAL_VARIABLE | 应用于局部变量 |
ElementType.ANNOTATION_TYPE | 应用于注解类型 |
ElementType.PACKAGE | 应用于包 |
ElementType.TYPE_PARAMETER | 1.8版本新增,应用于类型变量) |
ElementType.TYPE_USE | 1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型) |
@Retention 表明该注解的生命周期
生命周期类型 | 描述 |
---|---|
RetentionPolicy.SOURCE | 编译时被丢弃,不包含在类文件中 |
RetentionPolicy.CLASS | JVM加载时被丢弃,包含在类文件中,默认值 |
RetentionPolicy.RUNTIME | 由JVM 加载,包含在类文件中,在运行时可以被获取到 |
@Document 表明该注解标记的元素可以被Javadoc 或类似的工具文档化
@Inherited 表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解
文章作者 卢森林
上次更新 2020-08-02