一、java语言基础
1.Java 语言简介
1)杂谈
跨平台的java:可以在很多操作系统中使用
[外链图片转存失败(img-OSQ1Hvec-1564145204960)(G:\千锋实训\图片\捕获.PNG)]
- Java程序的类型:
软件类型 | 区别 | 例子 |
---|---|---|
B-S | 一般是以网页的方式当作客户端的形式,网页也是存储在后端服务器里的,发送请求后才会传输给客户端 | 淘宝 |
C-S | 需要下载客户端安装包 | 英雄联盟 |
- 一个字节是八位(电脑中一位是八个晶体管,一个晶体管只有两种状态),bit、byte、kb、mb、gb、tb、pb、eb,zb,yb,他们之间的都是1024的关系
- 字符编码与字符集uencode是对utf-8的二次编码
- Java是应用服务器中的常用语言
- 全角和半角:存储量少一半
2) java开始
-
JDK的安装
JDK每个目录的用处:
- bin:可执行文件,这里存储的是编译器和工具
- include:用于编译本地方法的文件,java和JVM交互用的头文件
- jre:java运行环境文件
- lib:是存放java类库文件
- src.zip:存放的是类库源文件
-
JDK,JRE,JVM
-
jdk:开发工具包,
-
JRE:java程序运行环境,但是只能够运行.class文件,因此需要现在JDK.bin中将java文件编译成.class文件,然后再运行,jre中有两个主要的目录,一个是bin,可以理解成里面存放了JVM,还有一个是lib,里面存放的是JVM工作所需要的类库
-
jvm:java虚拟机,运行.class文件的地方,将.class文件解释给计算机运行的文件
-
JRE在jdk中,属于JDK的一个文件
-
JVM存放在JRE的bin目录下
-
-
环境变量配置
最好把bean目录放在最前面
首先配置JAVA_HOME,然后配置path(path路径:jdk下面的bin绝对路径)
环境配置作用:使得程序能够有运行环境能够去运行,能够在任意位置使用这个环境变量,在bean目录下能够使用
-
为什么教程都是配置3个环境?
答:以前的jdk无法自己找到自己的文件,因此需要人工配置自己文件在哪里。新的jdk可以自己找到所需的文件
-
-
第一个程序Hello World:
//public 关键字,用于表示所修饰的类,变量,方法是公共的,任何相应的对象或类都可以调用 //class 标识符。表明这是一个类,类名需要大写,一般使用驼峰命名法,每个单词的第一个字母都是要大写 public class Hello(){ //Java程序的入口:mian方法 //static 关键字,用于修饰变量时,表示该变量属于类变量,全部的对象都共用这一个变量,修饰方法是,表明该方法可以通过类名调用,也可以通过对象调用 //void 关键字,表示修饰的方法输出的是空值,即是不输出 //形参:向主方法中传入0个或者一个或者若干个字符串 public static void mian(String args[]){ //在控制台输出 //单引号表示的是字符,双引号表示的是字符串 System.out.println("Hello World"); } }
注意:主方法必须是public static void main(String args[]){},一定是这样,这是程序的入口
JavaFX是一个 Java 的图形和媒体工具包。它使得Java应用程序开发者可以方便的设计开发富客户应用(Rich Client Application)。
[外链图片转存失败(img-DyFzTVvS-1564145204963)(G:\千锋实训\图片\mian方法不标准错误.PNG)]
-
使用**javac 文件路径(包括后缀)可以编译该java文件,使得文件变成.class*文件,可以使用 java 文件名 运行
3)关键字与标识符
关键字
-
关键字是在取名字的时候不能用的,还是不够严谨,如果类名是关键字,则无法编译,非法表达式开始,一般是标识符使用了关键字或者是出现语法错误。
main是不是java中的关键字?java中的main不是关键字,是一个不可改变的类名,是程序的入口,但是如果主方法不叫main那便不是一个主方法,只是一个普通方法。
[外链图片转存失败(img-BwAH6Sqm-1564145204963)(G:\千锋实训\图片\标识符使用关键字.PNG)]
-
关键字有哪些:
- 权限修饰词(访问控制) public private protected
- 类、方法、变量修饰符 static final abstract
- 程序控制符(中断,停止,分支,循环)
- 异常处理 try catch finally throw throws
- 包相关:import ,package
- 基本类型
- 变量引用:super this void
- 保留字:goto,const
标识符
由字母,数字,下划线,美元符号组成,首字符不能使用数字,只能使用字母,一般使用小写。 String类可以使用对象String,String不是关键字
标识符命名一般规则:
- 类名第一个字母大写
- 变量的一个字母小写
- 可以使用驼峰命名法或者使用下划线隔开每一个字符
4)变量与常量
- 变量:用于存储数据,变量存储的数据是可以改变的,临时存储数据,变量去名符合标识符的取名方式,不过一般使用驼峰命名法(单词的第一个首字母大写,但是一般第一个单词的首字母不用大写)
- 常量:不能改表的变量就是常量,使用final修饰的变量,有一些基本类型没有常量,或者说变成常量后会被警告比如byte,short
- 一个等于号 = 是用来赋值,两个是判断是否相等
5)数据类型
分类为两种:基本数据类型,引用数据类型。
数据类型 | 类型说明 | 长度 | 注意要点 | 字节长度 |
---|---|---|---|---|
int | 普通长度整型数据 | -231~231-1(四个字节) | 4 | |
byte | 字节长度整型数据 | -27~27-1(一个字节) | 没有常量 | 1 |
short | 短长度整型数据 | -215~215-1(两个字节) | 没有常量 | 2 |
long | 长整形数据 | -263-263-1(八个字节) | 常量后加L | 8 |
char | 字符数据 | 0~65536 | 2 | |
float | 浮点数数据 | 10-38~1038和-1038~10-38 | 常量后面加F或f | 4 |
double | 双精度浮点数数据 | 10-308~10308和-10308~10-308 | 常量后可以加D | 8 |
boolean | 布尔数据 | 只有ture和false |
-
自动转型:精度低的转换到精度高的可以自动转型
-
强制转型:精度高的转换到精度低的 需要强制转型,牵连到向上转型,向下转型(上下关系是子类父类树)
(类型名)要转换的值
数据类型按精度从低到高排序
byte–>short–>char–>int–>long–>float–>double
数据类型转换注意事项
- 将数据从低到高转换系统自动完成
- 将数据从高到底转换需要使用显示类型转换:(类型名)要转换的值 但是精度会损失
基本类型的包装
byte | Byte |
---|---|
short | Short |
int | Integer |
long | Long |
boolean | Boolean |
char | Charctar |
float | Float |
double | Double |
包装类型去基本类型的区别:
- 基本类型不能去在集合中使用
- 包装类型的默认类型是Null,基本类型的默认类型是0,因为包装类型的是类
6)键盘输入
java提供了在java.util包中有一个Scanner类,这个类可以从控制台中获取键盘输入的数据
Scanner reader=new Scanner(System.in);
//可以通过Scanner对象调用方法
// 键盘输入无法直接获取char类型的数据,需要显示String 类型的然后转变(使用方法)
7)运算符
- 算术运算符:+,-,*,/,%
- 逻辑运算符:&& ,||,!
- 比较运算符
- 赋值运算符
8)分支语句
分支语句即是根据不同的条件判定做不同的事情
-
if-else分支:
if(判定公式){ 代码块1; } else{ 代码块2; }
-
switch-case语句
switch(int/short/char/byte object){ case object1: ... case objectn: default: ... }
//只适用于等值比较,在JKD1.7之后可以比较String类型数据,原本只有byte,shor,int,char
9)循环语句
1.do-while
### 9)循环语句
1. do-while
```java
do{
循环体;
}while(判定公式)
//先执行循环体然后才会执行判定公式,在需要执行业务后才改变变量的时候使用do-while比较方便些,一般是执行成功或失败有一定前提条件去改变变量的时候才会使用。
-
while
while(判定公式){ 循环体; } //一般而言,不需要管循环体执行的过程以及内容的时候使用while比较合适
-
for
for(变量的声明以及初始化;判定公式;变量的改变){ 循环体; } //变量的初始化:变量可以在外面声明,在外面初始化一次,但是必须在for循环中再次初始化才不会由编译报错 //判定公式:判定公式是一个给出for循环什么时候停止的条件,可以出初始化的变量无关,但必须要给出一个boolean值 //使用for循环,一般是须知最大循环次数的时候使用,为了减小能耗,内存空间的消耗,一般不在循环体内声明变量
测试:
- 如果将判定公式换成赋值,也可以运行
[外链图片转存失败(img-nhpRtzjX-1564145204964)(G:\千锋实训\图片\for循环测试.PNG)]
-
判定公式与初始化的变量无关也可以运行
[外链图片转存失败(img-1ayPElzM-1564145204965)(G:\千锋实训\图片\for循环测试2.PNG)]
注意:不要再循环体内声明变量
-
关键字:
- break:从当前循环语句中跳出去
- continua:结束本次循环,即不再执行continua下面的循环语句,进行下一次循环
- return:结束程序,如果什么不返回,就直接中止程序,如果return后面还有逻辑代码块,也就是不是该段程序的最后阶段会报错
2.java初步
1)String类:字符串类
-
这是一个不可以改变的类,字符串类型不属于基本数据类型,是赢引用数据类型,字符串就是有字符拼接而成的组合体
-
String类在java.long包里面,java.long包里面提供了java语言程序设计的基础类(基本数据类型的封装类,Class,Math,线程类),java.long包中的类调用的时候不需要import7
-
一个类的构造方法可以传入该类对象作为参数
-
String类的构造方法
//无参构造方法 public String(){} //参数是String类型的构造方法 public String(String string){} //参数是字符数组的构造方法 public String(char[] ch){} //取字符数组一个片段的构造方法,指定字节是否在BMP中,是否是一个有效的Unicode代码点值 public String (char[] ch,int frist,int count){}
[外链图片转存失败(img-CGf5c2N3-1564145204965)(G:\千锋实训\图片\String类测试.PNG)]
-
String类中的常用方法
- 返回字符串长度
public int length(){ return value.leagth(); }
[外链图片转存失败(img-AyoPNAdM-1564145204965)(G:\千锋实训\图片\String类常用方法.PNG)]
2)方法
-
方法相当于一个动作
方法的语法 权限修饰词 (默认动态/静态关键字) 返回值类型 (标识符)方法名(传参数据类型 声明,...){ }
-
方法的重载:方法名相同,但是方法中传参类型或个数不同
重载与方法返回值类型无关,在调用方法的时候是按照方法名以及方法中的参数类型以及参数数量来寻找参数的,知道运行结束才会知道返回的是个什么样的值
3)数组
-
数组的底层存储:数组是存储在堆内存中的,在堆内存中分出一块内存,给出一个内存地址
-
数组的声明:
- 数据类型 变量名[ ];
- 数据类型[ ] 变量名;
-
数组的实例化
变量名=new 数据类型[需要给出长度];
-
数组的初始化
- 数据类型 变量名[ ]={对应类型的数据,之间使用逗号隔开} 一定需要带上数组的声明
- 变量名[下标/索引]=对应类型数据,只能一个;
- 使用for循环
-
使用数组的方法
- 长度:数组名.length
-
二维数组的存储:二维数组也就是一维数组的复杂版,就是在一维数组中存储一个个一维数组的内存地址
[外链图片转存失败(img-RLYvxLUB-1564145204966)(G:\千锋实训\图片\二维数组存储图.PNG)]
-
二维数组的声明与初始化
//声明和一维数组差不多 int a[][]; int[][] a; //初始化的时候必去给出第一个中括号的长度,初始化时底层需要知道这个数组有多长 int a[][]=new int[4][];
4)类与对象
a.类
-
类的定义:类是有相同属性以及相同行为的事物的集合
-
类的创建:
//public 修饰类的权限,表示该类可以被任何类调用 //class 是类的标识,告诉程序JVM虚拟机这是一个类 //类名一般第一个字符大写,类名是标识符,一般使用驼峰命名法 public class 类名(一般开头大写){ //静态代码块,在类加载的时候先执行静态代码块,并且在线程运行生命走起只会加载一次。类加载指的是new成对象之后 static{ } //类变量与普通变量,使用static 修饰的变量称之为类变量,也可以叫静态变量,类变量是在声明对象是时是不会给这个变量开辟新的内存空间,全部该类的对象共用一个地址,因此,只要一个修改后,其他对象的改变量值都会改变 //属性封装:使用privated修饰的属性,不能别其他类直接访问,可以通过在该类中创建输出和输入这个类的get,set方法去获取这个变量值 属性代码块; //静态方法: 就是使用static修饰的方法,可以直接使用类名调用或者使用对象调用 方法代码块; }
b.对象
-
对象的定义:一个具有某类的所有特征而且有自己特征的个体
-
对象的创建:对象是来自一个类,只有有了类才会有对象
//对象名是标识符,一般第一个字母是小写,一般使用驼峰命名法 //类中一般是有构造方法,默认是无参构造方法,如果一个类中有了有参构造方法一定还要给一个无参构造方法。如果是有参狗找方法需要在创造对象的时候添加参数 //new 是关键字,表示创建一个新的类。 //第二个类名可以是子类名,这是使用了Java的向上转型。但是调用的是子类的方法 类名 对象名=new 类名()
-
类名()使用的该类的构造方法
-
方法的调用
使用类名调用static修饰的方法 类名.方法; 使用类的对象调用方法 对象。方法;
- 静态方法的调用可以使用类名调用静态方法和静态属性。
-
构造方法:
-
什么是构造方法:就是在构造这个类的对象时会自动调用的方法
-
构造方法的作用:一般使用来给对象中的属性赋值,但是也可以是像普通方法一下输出什么的,但是会在创建对象的时候自动调用。
-
构造方法的语法:
//使用public修饰构造方法是可以在创建对象的时候自动调用,也可以使用其他权限修饰词修饰 public 类名(){ }
-
构造方法的注意点:
- 首先是构造方法可以由形参
- 构造方法可以被重载
-
构造方法的使用:
- 首先是如果类没有构造方法的话会先给一个默认的无参构造方法,方法体中也没有任何逻辑,只是为了让方便实例化对象。
- 在写一个类的逻辑的时候,如果有了有参构造方法也要给一个无参构造方法,这是潜规则
- 构造方法可以被重载
- 构造方法不能被继承,是因为从语法上,构造方法的方法名是类名,如果被继承给了子类,而子类的构造方法名是子类名,那个从父类哪里继承的就不是子类的构造方法并且也不符合普通方法的语法,然后是从逻辑上来说,子类无法继承父类的构造方法,子类和父类虽然有一定的继承关系,但是子类也有很多不同于父类的方法,因此设计的时候不允许子类继承父类的构造方法。
- 子类中可以使用父类的构造方法,子类可以在构造方法中使用super关键字调用父类的构造方法。但是必须放在第一行。后面的代码也会运行,。
-
5)封装、继承、多态
1)封装
-
封装的理解:将属性或者代码块装起来,不让别人看见,只有在使用的时候才调用
-
封装的方式:
-
属性封装:使用修饰词private,是的除了本类可以看见此属性,其他类只有调用类中的方法,不能通过对象直接调用的方式查看此属性
封装后创建set与get方法去输入和输入这个属性
set()方法:向set方法中传入一个参数,然后赋值给该对象的成员变量
get()方法:使用这个方法是输出对应的属性
-
功能封装:就是使用方法将逻辑封装在一个方法中,然后使用这个方法的时候无法看键这个方法中的代码,但是可以使用个方法完成一定的逻辑。
-
this关键字:
无论时修饰方法还是修饰属性都是说明使用的时该类中的成员变量或成员方法
-
2)继承
-
继承的理解:
就犹如父亲和儿子之间的关系,子类会继承从父类中的属性以及方法,子类也可以有属于他自己的方法以及属性。子类也可以重写父类的方法。
-
继承:子类使用关键字 extends继承父类,子类完全继承父类的除了构造方法以及私有方法,私有变量的所有方法和变量
-
继承需要注意点:
- 首先是子类继承父类后,在子类中继承而来的属性和方法是隐藏的,在子类中调用父类的方法可以使用关键字super,但是可以直接通过子类对象调用
- 如果子类重写了父类的方法或者改变了父类的属性可以通过关键字super调用父类的方法和属性
- 如果父类是由abstract修饰的抽象类后,子类需要重写(实现)父类的抽象方法,但是abstract不能修饰属性。
- 一个子类只能继承一个父类
- Java中类不支持多继承,但是支持多重继承,但是接口支持多重继承
-
super关键字
super.变量:调用父类的变量
super.方法:调用父类的方法
super():只能在子类构造 方法中,调用父类的构造方法,而且必须放在构造方法的第一行
3)多态
- 多态定义:一个行为具有多个表现形式和表现能力,可以理解为一对多
- 多态的理解:比如一个接口可以被多个类实现,然后接口中的方法别重写并且重写的方法可以不一样这就是多态
- 多态的例子
- 接口
- 向上转型
- 抽象类
4)成员变量、局部变量、类变量
-
成员变量:在类中创建的属性
-
局部变量:在方法中创建的变量
-
两者的区别
变量类型 创建区域 能否被修饰 内存中的位置 初始化 生命周期 成员变量(全局变量) 类中 能 创建对象后存放在JVM虚拟机堆里 可以被初始化 对象创建到使用完后对象销毁 局部变量 方法中 不能 使用方法时和方法一起压入栈中 不能被默认初始化,必须自己属于一个值 方法开始到逻辑结束 -
类变量:也叫做静态变量,使用static修饰的变量,这个类即使创建多个对象也只会创建一个变量,属于共享变量,然后在物理内存中也只会创建一个
5)static 关键字(静态)
-
静态属性:存在于永久代中,只有一个副本。
-
静态代码块:
static { }
静态代码块:在加载类的时候就直接先运行静态代码块,然后在整个进程期间只执行一次
-
静态方法:就是使用static修饰的方法,可以直接使用类名调用或者使用对象调用
-
静态方法中不能使用直接非静态方法以及静态属性,如果要使用的话需要可以用对象调用或者添加static关键字
-
静态方法,静态变量可以被继承,接口中不能有静态抽象方法,但是接口中可以有静态非抽象方法
-
静态变量与普通成员变量 的区别
属性 归属不同 调用方式不同 内存中出现的时机不同 内存的位置不同 静态属性 类 对象.属性/类.属性 类的字节码文件 静态区 普通成员属性 对象 对象.属性 对象创建的时候 堆
6)重写
- 重写的定义:在子类继承父类后,子类可以重新书写父类的方法,但是要求是子类的方法名,参数类型和个数以及返回值都一样。如果返回值不一样的话会直接报错,无法编译
6)抽象类
-
抽象类的定义:抽象类就是使用abstract修饰的类
-
抽象类中:抽象类中有抽象方法(抽象方法:使用abstract修饰的方法,并且没有方法的主体),也可以没有抽象方法
-
抽象类被继承:子类需要实现抽象类的抽象方法(重写),如果子类也是抽象类,那么子类既可以重写也可以不重写。
-
抽象类继承抽象类或者实现接口时,可以不重写抽象方法,也可以重写,子类继承抽象类需要重写抽象方法。
7)接口
-
接口的定义:有一定规章制度但是没有明确是什么规章制度需要使用这个接口的事物去规定接口的
-
接口 的语法:
interface 接口名{ }
-
接口的作用:用于多个类有共同行为,将其统一起来是的看起来更有联系行。
-
接口中的内容:
-
接口存放在方法体重
-
属性:默认是常量,省略了final关键字
-
方法:默认静态方法,省略了abstract关键字,并且没有方法的主体。
-
-
接口 的使用:
- 接口可以多继承接口,但是不能实现接口。
- 接口可以被抽象类实现,抽象类可以不用重写抽象方法
- 接口可以被普通类实现,普通类必须重写抽象方法。
8)向上转型与向下转型
类与类之间有了继承关系的时候。
-
向上转型:子类实例化之后赋值给父类的声明,向上转型后可以使用子类的非继承方法
是安全的。
-
向下转型;不安全,需要强制转换
-
instanceof:使用一个对象调用,需要传入一个类名,返回的是Boolean值,如果这个类创建了这个类或者是这个类的子类创建了这个对象则返回true。
9)final关键字
- 修饰属性:该属性变成常量
- 修饰方法:该方法继承后不能被修改,但是可以在被实现后添加一个final关键字
- 修饰类:该类不能被继承
?)JVM虚拟机
java虚拟机有
栈:
堆:老生代,新生代,永生代(方法区:静态区,常量池)
- 类。接口,枚举编译后都是*.class文件,放在方法区,
- 静态代码块以及静态方法是存放在静态区
- 成员变量:放在方法区,变量实例化放在方法区域,赋值的值放常量池。
- 局部变量:放在栈中
- 方法放在方法区中,调用方法的时候在将方法压入栈中
- 无论时堆和栈都是在内存中开辟一个内存,然后将不同数据放在不同的内存中加以区分
首先两个字符串中加上同一个字符后地址不一样
字符串常量值
-
String str=new String(“a”);
声明并实例化这样的对象,首先,这里有三个对象,按照创造过程来说就是,首先是计算机先在常量池中查早是否有这个常量,如果有 的话就直接将值赋值给new String()这个没有名字的对象,没有就先在常量池中创建这个常量,然后将这个对象赋值给str这个对象。
-
str=str+“a”;
由于String类型是常量,然后这个过程是先创建一个无名的新字符串常量,然后赋值给str,也就是说str 的对象已经不是原来的对象,是一个新对象
-
str1=str+“a”;
str1与str不是一个对象,并且里面的值相同,但是不是一个对象。eg:两个对象中的属性值完全相同,但是他们一定不是同一个对象,对于非静态属性来说,如果改变其中一个对象的属性值,另外一个对象的属性值是不会变的。
二、编程问题思考方式
在学习方法的时候需要考虑的
- 这个方法的作用是什么?
- 这个方法需要传入什么参数?输出什么参数?
- 这个方法如何被使用?(动态/静态)
- 这个方法的原理是什么?
编写逻辑的时候
- 首先要考虑这是个什么问题?即分析问题所在,需要知道这个问题需要我们做什么
- 然后要考虑怎么去解决这个问题,也就是需要什么样的逻辑去解决这个问题?
- 需不需要创建类,对象,属性等等,每一个属性变量对象都有意义。
- 编写代码是注意编写规范(尽量分开些)以及注释
- 编写完了之后需要做一个测试
三、千峰视频
1. java多线程
1)串行与并发
- 串行的理解:一个一个的运行
- 并发:宏观的同时进行
- 程序中的结构一般是串行加并发
2)进程与线程
进程和线程都是为了实现并发而存在的
- 进程:是对一个程序运行所需要的资源的描述,一般情况下不会再程序中开辟进程,因为进程资源不共享
- 线程:一个任务执行的最小单元,进程包含线程,一个进程中至少有一个线程,进程中没有线程将会被停止,线程中共享资源时临界资源。
3)线程的生命周期
-
生命周期:
将一个对象被实例化完成到这个对象被使用完被销毁成为对象的生命周期
-
线程的生命周期:线程被实例化完成,线程在java中也是一个对象,到被销毁是线程的生命周期
-
线程的状态:
新生态:new状态,被实例化完成,没做任何操作
就绪态:Ready 线程已经被开启,开始争抢cpu时间片
运行态:抢到了cpu时间片,开始执行这个线程中的逻辑
阻塞态:interupt 在运行的过程中收到某些操作的影响,放弃了获取的cpu时间片,并且不再去参与cpu时间片的争强,处于挂起状态
死亡态:一个线程对象被销毁
[外链图片转存失败(img-FG5VZKIS-1564145204966)(G:\千锋实训\图片\线程生命周期.PNG)]
-
线程生命周期:
- 新生态——>就绪态:在java程序中调用start方法将线程从新生态转化成就绪态
- 就绪态——>运行态:在就绪态的时候就是一个争抢cpu时间片的状态,如果抢到了时间片就会变成运行态
- 运行态——>阻塞态:1. 等待用户交互,2.使用sleep睡眠方法,3.使用join将两个线程合并
4)线程的开辟
-
线程实例化:
常见的两种方式:
-
线程是一个类,可以继承Thread类,然后自定义一个线程类
- 重写run方法:让线程并发执行的任务写道run方法中,然后实例化后调用start方法是现成启动,start方法会开启一个新的线程来执行run中的逻辑,如果自己调用run方法不会开启新的线程或者不会进入就绪状态。
- 使用场景:可读性更强,不够直观,java是单继承的。
-
构造方法有一个runnable接口,通过runnable接口的的实现类对象,可以使用匿名内部类。
-
实例化完成,线程在java中也是一个对象,到被销毁是线程的生命周期
-
线程的状态:
新生态:new状态,被实例化完成,没做任何操作
就绪态:Ready 线程已经被开启,开始争抢cpu时间片
运行态:抢到了cpu时间片,开始执行这个线程中的逻辑
阻塞态:interupt 在运行的过程中收到某些操作的影响,放弃了获取的cpu时间片,并且不再去参与cpu时间片的争强,处于挂起状态
死亡态:一个线程对象被销毁
[外链图片转存中…(img-FG5VZKIS-1564145204966)]
-
线程生命周期:
- 新生态——>就绪态:在java程序中调用start方法将线程从新生态转化成就绪态
- 就绪态——>运行态:在就绪态的时候就是一个争抢cpu时间片的状态,如果抢到了时间片就会变成运行态
- 运行态——>阻塞态:1. 等待用户交互,2.使用sleep睡眠方法,3.使用join将两个线程合并
4)线程的开辟
-
线程实例化:
常见的两种方式:
-
线程是一个类,可以继承Thread类,然后自定义一个线程类
- 重写run方法:让线程并发执行的任务写道run方法中,然后实例化后调用start方法是现成启动,start方法会开启一个新的线程来执行run中的逻辑,如果自己调用run方法不会开启新的线程或者不会进入就绪状态。
- 使用场景:可读性更强,不够直观,java是单继承的。
-
构造方法有一个runnable接口,通过runnable接口的的实现类对象,可以使用匿名内部类。
-