当前位置: 首页 > news >正文

学习日记-day17-5.27

完成目标:
 

知识点:

1.日期相关类_Calendar日历类
常用方法:int get(int field) ->返回给定日历字段的值void set(int field, int value)  :将给定的日历字段设置为指定的值void add(int field, int amount) :根据日历的规则,为给定的日历字段添加或者减去指定的时间量Date getTime():将Calendar转成Date对象field:代表的是日历字段-> 年 月 日 星期等,都是静态的    private static void calendar02() {Calendar calendar = Calendar.getInstance();//多态//int get(int field) ->返回给定日历字段的值int year = calendar.get(Calendar.YEAR);System.out.println("year = " + year);//void set(int field, int value)  :将给定的日历字段设置为指定的值//calendar.set(Calendar.YEAR,2028);//System.out.println(calendar.get(Calendar.YEAR));//void add(int field, int amount) :根据日历的规则,为给定的日历字段添加或者减去指定的时间量calendar.add(Calendar.YEAR,-1);System.out.println(calendar.get(Calendar.YEAR));//Date getTime():将Calendar转成Date对象Date date = calendar.getTime();System.out.println("date = " + date);}扩展方法:void set(int year, int month, int date) -> 直接设置年月日=====================================================================================需求:键盘录入一个年份,判断这一年是闰年,还是平年步骤:1.创建Calendar对象2.创建Scanner对象,键盘录入一个年份3.调用set方法,传递年,月,日set(年,2,1) -> 国外是0-11,所以设置成2月就是代表3月  4.将day减1天(3月1日减1天,就是2月最后一天,知道2月最后一天了,就知道是平年还是闰年了)5.获取day判断平年还是闰年,输出结果    private static void calendar03() {//1.创建Calendar对象Calendar calendar = Calendar.getInstance();//2.创建Scanner对象,键盘录入一个年份Scanner sc = new Scanner(System.in);int year = sc.nextInt();//3.调用set方法,传递年,月,日//set(年,2,1) -> 国外是0-11,所以设置成2月就是代表3月calendar.set(year,2,1);//4.将day减1天(3月1日减1天,就是2月最后一天,知道2月最后一天了,就知道是平年还是闰年了)calendar.add(Calendar.DATE,-1);int day = calendar.get(Calendar.DATE);//5.获取day判断平年还是闰年,输出结果if (day==29){System.out.println("闰年");}else{System.out.println("平年");}}

知识点

核心内容

易混淆点

Date类弃用问题

Date类中多个方法已被弃用,由Calendar类替代

弃用方法与新方法的对应关系

Calendar类特性

抽象类,需通过getInstance()静态方法获取对象

抽象类不能直接实例化的特性

月份表示差异

国外月份从0开始计数(0-11对应国内1-12月)

月份数值需要+1才能对应国内习惯

Calendar核心字段

YEAR/MONTH/DAY_OF_MONTH/HOUR/MINUTE/SECOND等时间字段

字段的静态属性和使用方式

关键方法应用

get()获取字段值; set()设置字段值; add()时间量加减; getTime()转Date对象

方法参数中字段常量的使用

闰年判断案例

通过设置3月1日再减1天获取2月最后一天

时区对日期计算的影响

多态应用

Calendar.getInstance()返回的是具体子类对象

实际运行时类型与声明类型差异

2.日期相关类_日期格式化类
1.概述:日期格式化类
2.构造:SimpleDateFormat(String pattern)
3.pattern:代表的是我们自己指定的日期格式字母不能改变,但是中间的连接符我们可以改变 yyyy-MM-dd HH:mm:ss  | 时间字母表示 | 说明 |
| ------------ | ---- |
| y            | 年   |
| M            | 月   |
| d            | 日   |
| H            | 时   |
| m            | 分   |
| s            | 秒   |## 2.SimpleDateFormat常用方法1.String format(Date date) -> 将Date对象按照指定的格式转成String 
2.Date parse(String source)-> 将符合日期格式的字符串转成Date对象      public class Demo03SimpleDateFormat {public static void main(String[] args) throws ParseException {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//1.String format(Date date) -> 将Date对象按照指定的格式转成StringString time1 = sdf.format(new Date());System.out.println("time1 = " + time1);//2.Date parse(String source)-> 将符合日期格式的字符串转成Date对象String time2 = "2000-10-10 10:10:10";Date date = sdf.parse(time2);System.out.println("date = " + date);}
}

知识点

核心内容

重点

SimpleDateFormat类概述

用于日期格式化的工具类,可将Date对象转换为指定格式的字符串,或反向解析字符串为Date对象

构造方法参数为日期模式字符串(字母不可变,连接符可自定义)

日期模式规则

y-年、M-月、d-日、H-时、m-分、s-秒;

大小写敏感(如M与m区分月与分)

易混淆:MM(月) vs mm(分)

format方法

将Date对象按模式格式化为字符串(如yyyy-MM-dd HH:mm:ss)

输出结果与模式严格匹配

parse方法

将符合模式的字符串解析为Date对象

编译时异常需处理(ParseException);格式不匹配会报错

连接符自定义

模式中非字母符号(如/、-)可自由替换,但字母顺序不可变

错误示例:mm/dd/yyyy会导致“分日年月”逻辑混乱

3.日期相关类_jdk8新日期类
1.概述:LocalDate是一个不可变的日期时间对象,表示日期,通常被视为年月日
2.获取:static LocalDate now()  -> 创建LocalDate对象static LocalDate of(int year, int month, int dayOfMonth)  -> 创建LocalDate对象,设置年月日   public class Demo04LocalDate {public static void main(String[] args) {//static LocalDate now()  -> 创建LocalDate对象LocalDate localDate = LocalDate.now();System.out.println("localDate = " + localDate);//static LocalDate of(int year, int month, int dayOfMonth)  -> 创建LocalDate对象,设置年月日LocalDate localDate1 = LocalDate.of(2000, 10, 10);System.out.println("localDate1 = " + localDate1);}
}### 1.2.LocalDateTime对象1.LocalDateTime概述:LocalDateTime是一个不可变的日期时间对象,代表日期时间,通常被视为年 - 月 - 日 - 时 - 分 - 秒。2.获取:
static LocalDateTime now()  创建LocalDateTime对象
static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second) 创建LocalDateTime对象,设置年月日时分秒public class Demo05LocalDateTime {public static void main(String[] args) {//static LocalDateTime now()  创建LocalDateTime对象LocalDateTime localDateTime = LocalDateTime.now();System.out.println("localDateTime = " + localDateTime);//static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second) 创建LocalDateTime对象,设置年月日时分秒LocalDateTime localDateTime1 = LocalDateTime.of(2000, 10, 10, 10, 10, 10);System.out.println("localDateTime1 = " + localDateTime1);}
}### 1.3.获取日期字段的方法 : 名字是get开头int getYear()->获取年份
int getMonthValue()->获取月份
int getDayOfMonth()->获取月中的第几天private static void get() {LocalDate localDate = LocalDate.now();//int getYear()->获取年份System.out.println(localDate.getYear());//int getMonthValue()->获取月份System.out.println(localDate.getMonthValue());//int getDayOfMonth()->获取月中的第几天System.out.println(localDate.getDayOfMonth());}### 1.4.设置日期字段的方法 : 名字是with开头LocalDate withYear(int year):设置年份
LocalDate withMonth(int month):设置月份
LocalDate withDayOfMonth(int day):设置月中的天数private static void with() {LocalDate localDate = LocalDate.now();//LocalDate withYear(int year):设置年份//LocalDate localDate1 = localDate.withYear(2000);//System.out.println(localDate1);//LocalDate withMonth(int month):设置月份//LocalDate localDate2 = localDate1.withMonth(10);//System.out.println("localDate2 = " + localDate2);//LocalDate withDayOfMonth(int day):设置月中的天数//LocalDate localDate3 = localDate2.withDayOfMonth(10);//System.out.println("localDate3 = " + localDate3);LocalDate localDate1 = localDate.withYear(2000).withMonth(10).withDayOfMonth(10);System.out.println("localDate1 = " + localDate1);}### 1.5.日期字段偏移设置日期字段的偏移量,方法名plus开头,向后偏移
设置日期字段的偏移量,方法名minus开头,向前偏移/*向后偏移 -> plus开头方法向前偏移 -> minus开头方法*/private static void plusAndMinus() {LocalDate localDate = LocalDate.now();// LocalDate localDate1 = localDate.plusYears(1L);// System.out.println("localDate1 = " + localDate1);LocalDate localDate1 = localDate.minusYears(1L);System.out.println("localDate1 = " + localDate1);}
### 2.1 Period 计算日期之间的偏差方法:static Period between(LocalDate d1,LocalDate d2):计算两个日期之间的差值getYears()->获取相差的年getMonths()->获取相差的月getDays()->获取相差的天private static void period() {LocalDate local1 = LocalDate.of(2022, 12, 12);LocalDate local2 = LocalDate.of(2021, 11, 11);Period period = Period.between(local2, local1);System.out.println(period.getYears());System.out.println(period.getMonths());System.out.println(period.getDays());}### 2.2 Duration计算时间之间的偏差1.static Duration between(Temporal startInclusive, Temporal endExclusive)  -> 计算时间差
2.Temporal : 是一个接口实现类:LocalDate LocalDateTime      
3.参数需要传递 Temporal 的实现类对象, 注意要传递LocalDateTime因为Duration计算精确时间偏差,所以需要传递能操作精确时间的 LocalDateTime            
4.利用Dutation获取相差的时分秒 -> to开头toDays() :获取相差天数toHours(): 获取相差小时toMinutes():获取相差分钟toMillis():获取相差秒(毫秒)private static void duration() {LocalDateTime local1 = LocalDateTime.of(2022, 12, 12,12,12,12);LocalDateTime local2 = LocalDateTime.of(2021, 11, 11,11,11,11);Duration duration = Duration.between(local2, local1);System.out.println(duration.toDays());System.out.println(duration.toHours());System.out.println(duration.toMinutes());System.out.println(duration.toMillis());}如果计算年月日 ,就用Period如果计算时分秒,就用Duration## 3.DateTimeFormatter日期格式化类1.获取:static DateTimeFormatter ofPattern(String pattern)   -> 获取对象,指定格式
2.方法:String format(TemporalAccessor temporal)-> 将日期对象按照指定的规则转成String TemporalAccessor:接口,子接口有TemporalTemporal的实现类:LocalDate LocalDateTime    TemporalAccessor parse(CharSequence text)-> 将符合规则的字符串转成日期对象 如果想将TemporalAccessor转成我们常见的LocalDateTime日期对象,就需要用到LocalDateTime中的静态方法:static LocalDateTime from(TemporalAccessor temporal)  private static void parse() {DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String time = "2000-10-10 10:10:10";TemporalAccessor temporalAccessor = dtf.parse(time);//System.out.println(temporalAccessor);LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);System.out.println("localDateTime = " + localDateTime);}

知识点

核心内容

易混淆点

LocalDate

不可变日期对象,表示年月日; 创建方法:now()获取当前日期,of()设置指定日期

getMonth()返回枚举类型 vs getMonthValue()返回数字

LocalTime

不可变时间对象,表示时分秒; 同样使用now()和of()方法创建

与LocalDate的精度区别(是否包含时分秒)

LocalDateTime

不可变日期时间对象,组合LocalDate和LocalTime; 精确到纳秒级

必须使用LocalDateTime进行精确时间计算

字段操作

get开头方法获取字段值; with开头方法设置字段值(返回新对象); plus/minus方法进行日期偏移

链式调用时注意不可变性(每次操作生成新对象)

Period

计算两个LocalDate之间的年月日差值; between()方法+getYears/Months/Days获取结果

直接相减(2022-12 vs 2021-11 → 1年1月)

Duration

计算两个LocalDateTime之间的精确时间差;

between()方法+toDays/Hours/Minutes获取结果

必须使用LocalDateTime作为参数

DateTimeFormatter

替代SimpleDateFormat的格式化类; ofPattern()创建格式器;

format()日期转字符串;

parse()字符串转日期

需要TemporalAccessor接口处理,转换需通过LocalDateTime.from()

4.工具类_System系统相关类
| 方法                                                         | 说明                                                         |
| ------------------------------------------------------------ | ------------------------------------------------------------ |
| static long currentTimeMillis()                              | 返回以毫秒为单位的当前时间,可以测效率                        |
| static void exit(int status)                                 | 终止当前正在运行的 Java 虚拟机                               |
| static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length | 数组复制<br>src:源数组<br>srcPos:从源数组的哪个索引开始复制<br>dest:目标数组<br>ldestPos:从目标数组哪个索引开始粘贴<br>length:复制多少个元素 |public class Demo01System {public static void main(String[] args) {//currentTimeMillis();//exit();arraycopy();}/*static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)src:源数组srcPos:从源数组的哪个索引开始复制dest:目标数组destPos:从目标数组的哪个索引开始粘贴length:复制多少个元素*/private static void arraycopy() {int[] arr1 = {1,2,3,4,5};int[] arr2 = new int[10];System.arraycopy(arr1,0,arr2,0,5);for (int i = 0; i < arr2.length; i++) {System.out.print(arr2[i]+" ");}}private static void exit() {for (int i = 0; i < 100; i++) {if (i==5){System.exit(0);}System.out.println("helloworld"+i);}}private static void currentTimeMillis() {long time = System.currentTimeMillis();System.out.println("time = " + time);}
}

知识点

核心内容

重点

System工具类概述

系统相关工具类,构造方法私有化,所有方法均为静态

工具类的通用设计特点:构造私有+静态方法

currentTimeMillis()方法

返回当前时间的毫秒值,用于代码执行效率测试

注意时间戳的获取时机和差值计算

exit()方法

终止JVM运行,参数通常传0,会导致程序立即退出

与return语句的区别:影响整个虚拟机而非单个方法

arraycopy()方法

数组复制核心方法,5个参数:源数组、起始位、目标数组、起始位、复制长度

参数顺序和边界值容易混淆,需注意数组越界问题

工具类使用规范

通过类名直接调用静态方法,无需实例化

与普通类的实例化调用方式对比

5.工具类_Arrays数组工具类
| 方法                                               | 说明                                        |
| -------------------------------------------------- | ------------------------------------------- |
| static String toString(int[] a)                    | 按照格式打印数组元素<br>[元素1, 元素2, ...] |
| static void sort(int[] a)                          | 升序排序                                    |
| static int binarySearch(int[] a, int key)          | 二分查找(前提是升序)                        |
| static int[] copyOf(int[] original, int newLength) | 数组扩容                                    |public class Demo02Arrays {public static void main(String[] args) {int[] arr = {5,3,4,6,5,4,7};System.out.println(Arrays.toString(arr));System.out.println("==============");Arrays.sort(arr);System.out.println(Arrays.toString(arr));System.out.println("==============");int[] arr1 = {1,2,3,4,5,6,7};int index = Arrays.binarySearch(arr1, 3);System.out.println("index = " + index);System.out.println("==============");int[] arr2 = {1,2,3,4,5};int[] newArr = Arrays.copyOf(arr2, 10);System.out.println(Arrays.toString(newArr));arr2 = newArr;System.out.println(Arrays.toString(arr2));}
}

知识点

核心内容

重点

Arrays工具类概述

构造私有、方法静态、类名直接调用

构造私有化的意义(防止实例化)

toString()方法

按[元素1, 元素2...]格式打印数组

底层实现:StringBuilder拼接逻辑(判空、索引处理)

sort()方法

数组升序排序(非冒泡排序,底层为优化算法)

与手动实现冒泡排序的性能对比

binarySearch()方法

二分查找(前提:数组已升序

未排序时调用后果(结果错误)

copyOf()方法

数组扩容(底层依赖System.arraycopy)

扩容原理:新数组创建 + 老数据复制

方法封装思想

理解底层原理后复用封装方法

为什么先学手动实现(加深原理理解)

6.包装类
1.概述:就是基本类型对应的类(包装类),我们需要将基本类型转成包装类,从而让基本类型拥有类的特性(说白了,将基本类型转成包装类之后,就可以使用包装类中的方法操作数据)2.为啥要学包装类:a.将来有一些特定场景,特定操作,比如调用方法传递包装类比如:ArrayList集合,里面有一个方法add(Integer i),此时我们不能调用add方法之后直接传递基本类型,因为引用类型不能直接接收基本类型的值,就需要先将基本类型转成包装类,传递到add方法中b.将来我们还可以将包装类转成基本类型:包装类不能直接使用+ - * /,所以需要将包装类转成基本类型,才能使用+ - * /| 基本类型 | 包装类    |
| -------- | --------- |
| byte     | Byte      |
| short    | Short     |
| int      | Integer   |
| long     | Long      |
| float    | Float     |
| double   | Double    |
| char     | Charactor |
| boolean  | Boolean   |
### 2.1.Integer基本使用1.概述:Integer是int的包装类
2.构造:  不推荐使用了,但是还能用Integer(int value)Integer(String s) s必须是数字形式public class Demo01Integer {public static void main(String[] args) {Integer i1 = new Integer(10);System.out.println("i1 = " + i1);Integer i2 = new Integer("10");System.out.println("i2 = " + i2);System.out.println("================");Boolean b1 = new Boolean("true");System.out.println("b1 = " + b1);Boolean b2 = new Boolean("false");System.out.println("b2 = " + b2);Boolean b3 = new Boolean("True");System.out.println("b3 = " + b3);}
}===================================================1.装箱:将基本类型转成对应的包装类
2.方法:static Integer valueOf(int i)  static Integer valueOf(String s)  public class Demo02Integer {public static void main(String[] args) {Integer i1 = Integer.valueOf(10);System.out.println("i1 = " + i1);Integer i2 = Integer.valueOf("100");System.out.println("i2 = " + i2);}
}===================================================1.拆箱:将包装类转成基本类型
2.方法:int intValue();public class Demo03Integer {public static void main(String[] args) {Integer i1 = Integer.valueOf(10);System.out.println("i1 = " + i1);int i = i1.intValue();System.out.println("(i+10) = " + (i + 10));}
}
### 2.2.自动拆箱装箱1.拆箱和装箱很多时候都是自动完成的public class Demo04Integer {public static void main(String[] args) {Integer i = 10;//发生了自动装箱了Integer sum = i+10;//发生了自动拆箱装箱System.out.println("sum = " + sum);}
}public class Demo05Integer {public static void main(String[] args) {Integer i1 = 100;Integer i2 = 100;System.out.println(i1==i2);Integer i3 = 128;Integer i4 = 128;System.out.println(i3==i4);}}
## 3.基本类型和String之间的转换### 3.1 基本类型往String转1.方式1:+ 拼接
2.方式2:String中的静态方法static String valueOf(int i) private static void method01() {int i = 10;String s1 = i+"";System.out.println(s1+1);System.out.println("============");String s = String.valueOf(10);System.out.println(s+1);}===================================================
### 3.2 String转成基本数据类型每个包装类中都有一个类似的方法:  parseXXX| 位置    | 方法                                  | 说明                    |
| ------- | ------------------------------------- | ----------------------- |
| Byte    | static byte parseByte(String s)       | 将String转byte类型      |
| Short   | static short parseShort(String s)     | 将String转成short类型   |
| Integer | static int parseInt(String s)         | 将String转成int类型     |
| Long    | static long parseLong(String s)       | 将String转成long类型    |
| Float   | static float parseFloat(String s)     | 将String转成float类型   |
| Double  | static double parseDouble(String s)   | 将String转成double类型  |
| Boolean | static boolean parseBoolean(String s) | 将String转成boolean类型 |private static void method02() {int number = Integer.parseInt("1111");System.out.println(number+1);}1.在实际开发过程中如何定义一个标准javabean定义javabean的时候一般会将基本类型的属性定义成包装类型的属性  public class User {//private int uid;//用户idprivate Integer uid;//用户idprivate String username;//用户名private String password;//密码public User() {}public User(Integer uid, String username, String password) {this.uid = uid;this.username = username;this.password = password;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

1.举例:如果uid为Integer型,默认值是null

 2.将来javabean中的数据都是和数据库表联系起来的,我们可以将javabean中的数据添加到表中

  如果表中的uid为主键自增的,此时添加语句时uid中的数据不用我们单独维护赋值了,添加语句的sql语句就可以这样写:

   insert into user(uid,username,password) values (NULL,'金莲','36666');

 3.到时候,我们需要将javabean中封装的数据获取出来放到sql语句中,如果uid为主键自增,而且javabean中的uid为包装类型,默认值为NULL,这样就不用单独维护uid的值了,也不用先给javabean中的uid赋值,然后在保存到数据库中了,咱们就可以直接使用uid的默认值,将默认值放到sql语句的uid列中

 4.而且将javabean中的属性变成包装类,还可以使用包装类中的方法去操作此属性值。

知识点

核心内容

重点

包装类概念

基本数据类型对应的类,用于让基本类型拥有类特性(如方法调用)

int→Integer/char→Character与其他首字母大写规则不同

包装类作用

1. 使基本类型具备类特性;

2. 集合等场景强制要求包装类型;

3. 支持null值场景

ArrayList的add方法必须传Integer类型

装箱拆箱机制

自动装箱:Integer i = 10; 自动拆箱:i+10 → 实际调用intValue()

反编译可见编译器自动插入valueOf/intValue调用

缓存池机制

-128~127范围的Integer对象复用(通过IntegerCache内部类实现)

new Integer(100)==Integer.valueOf(100) 结果不同

类型转换方法

1. parseInt():String转int;

2. valueOf():String转Integer

数字格式异常风险(需处理NumberFormatException)

JavaBean规范

基本类型属性应定义为包装类型: - 支持null值(如数据库主键自增场景); - 可使用包装类方法

默认值差异:int默认0 vs Integer默认null

7.多线程

知识点

核心内容

重点

多线程基础

多线程是JAVA后期高阶部分的重要内容

多线程基础操作与高级应用的区别

进程定义

进程是内存中执行的应用程序,如QQ

进程与程序的区别,进程是执行中的程序

线程定义

线程是进程中最小的执行单元,负责程序运行

线程与进程的关系,线程在进程内

多线程程序

一个进程中可以有多个线程,称为多线程程序

多线程与单线程的区别

线程与CPU

CPU为每一个功能开辟通道,即线程,去内存中提取代码执行

线程是CPU与内存之间的通道

多线程使用场景

耗时操作、拷贝大文件、加载大量资源、聊天软件、服务器等

多线程提高CPU利用率,但不能绝对说提高效率

并发与并行

并行:多个指令在多个CPU上同时执行;并发:多个指令在单个CPU上交替执行

并发与并行的区别,交替与同时的执行方式

CPU调度

分时调度:线程轮流获取CPU使用权;抢占式调度:线程抢占CPU使用权

两种调度方式的区别,JAVA程序使用抢占式调度

主线程概念

主线程是CPU和内存之间为main方法开辟的通道

主线程与程序执行的关系,main方法占一个线程

8.多线程_创建线程方式1_继承Thread
## 1.第一种方式_extends Thread1.定义一个类,继承Thread
2.重写run方法,在run方法中设置线程任务(所谓的线程任务指的是此线程要干的具体的事儿,具体执行的代码)
3.创建自定义线程类的对象 
4.调用Thread中的start方法,开启线程,jvm自动调用run方法public class Test01 {public static void main(String[] args) {//创建线程对象MyThread t1 = new MyThread();//调用start方法,开启线程,jvm自动调用run方法t1.start();for (int i = 0; i < 10; i++) {System.out.println("main线程..........执行了"+i);}}
}public class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("MyThread...执行了"+i);}}
}

知识点

核心内容

重点

创建多线程的第一种方式

通过继承Thread类实现多线程

start()与run()方法的区别

Thread类结构

Thread类实现Runnable接口并重写run()方法

run()方法是线程任务执行入口

线程任务定义

在自定义线程类的run()方法中编写具体执行逻辑

线程任务代码需写在run()方法内

线程启动机制

必须调用start()方法才会真正创建新线程

直接调用run()只是普通方法调用

线程执行特性

多个线程会交替执行,顺序不确定

CPU调度导致每次执行结果可能不同

代码实现示例

MyThread继承Thread→重写run()→创建对象→调用start()

完整实现步骤需严格遵循

9.多线程_多线程运行原理

知识点

核心内容

重点

多线程内存运行机制

主线程与自定义线程在内存中拥有独立的栈空间,分别执行对应方法(如main()和run())

线程栈空间独立性(开新线程即新建栈空间)

线程启动规则

同一线程对象不可多次调用start(),需新建对象才能再次启动

重复调用start()会报异常

线程资源消耗

死循环创建线程会导致内存占满,系统无响应

实际应用需控制线程数量

线程生命周期

线程启动后执行run()方法,结束后栈空间释放

线程对象复用与新建的区别

10.多线程_Thread中常用方法
void start() -> 开启线程,jvm自动调用run方法
void run()  -> 设置线程任务,这个run方法是Thread重写的接口Runnable中的run方法
String getName()  -> 获取线程名字
void setName(String name) -> 给线程设置名字
static Thread currentThread() -> 获取正在执行的线程对象(此方法在哪个线程中使用,获取的就是哪个线程对象)   
static void sleep(long millis)->线程睡眠,超时后自动醒来继续执行,传递的是毫秒值    public class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 10; i++) {//线程睡眠try {Thread.sleep(1000L);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName()+"...执行了"+i);}}
}public class Test01 {public static void main(String[] args) throws InterruptedException {//创建线程对象MyThread t1 = new MyThread();//给线程设置名字t1.setName("金莲");//调用start方法,开启线程,jvm自动调用run方法t1.start();for (int i = 0; i < 10; i++) {Thread.sleep(1000L);System.out.println(Thread.currentThread().getName()+"线程..........执行了"+i);}}
}问题:为啥在重写的run方法中有异常只能try,不能throws原因:继承的Thread中的run方法没有抛异常,所以在子类中重写完run方法之后就不能抛,只能try

知识点

核心内容

重点

Thread类方法

start()方法开启线程并自动调用run()方法

start()与run()方法的区别

run()方法

设置线程任务的核心方法,

需重写Runnable接口

父类Thread中的run()方法未抛异常,子类重写后不能throws

线程命名

getName()获取线程名

setName()设置线程名

主线程默认名为"main",新建线程默认名为"Thread-N"

currentThread()

静态方法获取当前执行线程的引用

链式调用获取线程名:Thread.currentThread().getName()

sleep()方法

使线程暂停指定毫秒数(1000ms=1s)

编译时异常必须处理,run()中只能try-catch

线程执行控制

sleep()不影响其他线程执行

主线程与子线程的执行顺序不确定性

异常处理规则

子类重写方法时异常声明需与父类一致

Thread.run()未声明异常导致子类禁止throws

相关文章:

  • 计算机网络练习题
  • 网络:华为S5720-52X-SI交换机重置console密码
  • 涨薪技术|0到1学会性能测试第84课-Windows Sockets数据操作
  • Nest全栈到失业(一):Nest基础知识扫盲
  • LeetCode 118 题解--杨辉三角
  • leetcode每日一题(好几天之前的) -- 3068.最大节点价值之和
  • 什么是可重组机器人?
  • 【Day38】
  • SwaggerEndPoints 配置访问外部 Swagger 文档
  • 使用蓝耘元生代 MaaS 平台 API 工作流调用技巧与实践体验
  • 九级融智台阶与五大要素协同的量子化解析
  • 仿盒马》app开发技术分享-- 确认订单页(数据展示)(端云一体)
  • 迪宇电力绝缘胶垫四大优势,用特殊橡胶配方制成,具备多项实用优势
  • Day31 -js应用 -实例:webpack jQuery的使用及其隐含的安全问题
  • MySQL 窗口函数深度解析:语法、应用场景与性能优化
  • 理解vue-cli 中进行构建优化
  • 不同电脑同一个网络ip地址一样吗?如何更改
  • HTML Day02
  • C++—decltype
  • 大模型(5)——编码器(Encoder)、解码器(Decoder)
  • 网站建设与管理怎么样/青岛网络优化费用
  • 织梦网站建设案例/高级搜索引擎
  • 用dz做网站怎么设置数据库/什么是搜索引擎竞价推广
  • 西安网站优化招聘网/买外链有用吗
  • 济宁网站制作/品牌策划与推广
  • 自己做的网站怎么挣钱/欧美seo查询