回顾:
异常
-
什么异常
-
异常分类
- Error
- Exception
-
Exception分类
- 运行异常
- NullPointException
- ClassCastException
- …
- 检测异常
- ParseException
- …
- 运行异常
-
异常的处理
- try-catch
- try-catch-catch
- try-finally
try { //检测的代码 } catch (异常名称 e){ //出现这种异常,执行的代码 //catch定义执行结束,代码还会继续往下执行 } catch (异常名称 e){ //出现这种异常,执行的代码 //catch定义执行结束,代码还会继续往下执行 } try { //检测的代码 } finally { //一定执行的代码 } try { //检测的代码 } catch (异常名称 e){ //出现这种异常,执行的代码 //catch定义执行结束,执行finally中代码 } catch (异常名称 e){ //出现这种异常,执行的代码 //catch定义执行结束,执行finally中代码 } finally { //一定执行的代码 }
-
两个关键字
- throw
- 主动抛出异常,程序就不再往下执行
- 主动抛出的异常
- 运行异常
- 检测异常
- 需要在方法上使用throws声明,调用该方法可能会产生的异常
- 当你调用时,必须处理这个异常
int i = 9/0; chu(9,0); public int chu(int a, int b) throws FileNotFindException{ if(b == 0) { throw new FileNotFindException("b值不能为0"); // 主动抛出异常,产生一个错误 程序不再往下执行 } return a/b; }
- throws
- 在方法上使用throws声明,调用该方法可能会产生的异常发
- 在调用使用了throws声明异常的方法,他们的处理方法
- 我也不处理
- 在方法也抛出去
- 处理 try-catch
- 我也不处理
- throw
多线程
1. 进程和线程
进程:就是一个运行的程序(软件)。
现实中:做饭,打扫卫生
- 在同一个时间点,只能执行一个进行
- 宏观并行,微观串行
线程:就是进程一个步骤
- 线程是cpu调度的基本单位
- 一个进程中有多个线程,成为多线程
做饭: 买菜,洗菜,切菜,炒菜
打扫卫生:扫地,拖地,收拾东西
2. 进程和线程的区别
- 进程系统操作资源分配的最小单位
- 线程是CUP调度的最小单位
- 一个进程可以包含多个线程,最少要有一个线程
- 不同进程之间,资源是不能共享的
- 在同一个进程中的多个线程,是可以共享资源的
2.1 线程的组成
- cpu时间片段 : 分配多长时间,就执行多长时间,这是CPU随机决定的
- 堆:保存对象
- 栈:保存变量
- 常量池:保存常量对象 字符串
- 方法区:在类信息
3. 线程的创建
3.1 继承Thread类
package com.qf;
/*
* java.lang包中类,都不需要引入
*
* 1. 继承Thread类
* 2. 重写run方法
* 定义该线程被cpu调度时,执行的业务逻辑
*/
public class MyThread extends Thread{
public void run() {
for(int i=1; i<=100; i++) {
System.out.println(getName() + "---" +i);
}
}
}
package com.qf;
public class Demo01 {
public static void main(String[] args) {
//创建线程对象
MyThread t1 = new MyThread();
//启动线程,都可以竞争CPU的资源(main线程)
t1.start();
for(int i=1; i<=100; i++) {
System.out.println("main---" +i);
}
}
}
3.2 实现Runnable接口
package com.qf;
/*
* 1. 实现Runnable接口
* 2. 实现run方法
*/
public class YourThread implements Runnable{
@Override
public void run() {
for(int i=1; i<=100; i++) {
System.out.println(Thread.currentThread().getName() + "---" +i);
}
}
}
package com.qf;
public class Demo02 {
public static void main(String[] args) {
Runnable runnable = new YourThread();
Thread t = new Thread(runnable, "线程名02");
t.start();
MyThread t1 = new MyThread();
t1.setName("线程01");
t1.start();
}
}
4. 线程状态(基本)
- 新建:创建线程对象
- 就绪:
- 执行start()方法
- 时间片段执行结束,但是run方法没有执行完
- 运行: 处于cpu调度的时间片段内
- 终结:run方法执行结束
package com.qf;
public class MyThread extends Thread{
public void run() {
System.out.println("运行状态");
//业务逻辑
System.out.println("run方法执行结束,终结状态");
}
}
package com.qf;
public class Demo01 {
public static void main(String[] args) {
//当创建了一个对象时,新建状态
System.out.println("新建状态");
MyThread t = new MyThread();
/*
* 就绪状态
* 它才能竞争CPU的资源,执行其run方法
*/
System.out.println("就绪状态");
t.start();
}
}
2. 线程状态(等待)
线程可执行相应的方法,进入等待状态
-
yield
礼让 重新回到就绪状态
package com.qf;
public class Demo02 {
public static void main(String[] args) {
/*
* yield : 礼让 重新回到就绪状态
*/
Thread02 t = new Thread02();
Thread02 t2 = new Thread02();
Thread02 t3 = new Thread02();
t.start();
t2.start();
t3.start();
}
}
class Thread02 extends Thread {
@Override
public void run() {
for(int i=1; i<=50; i++) {
System.out.println(getName()+"---"+i);
if (i%7 == 0) {
yield();
}
}
}
}
-
sleep 休眠
进入休眠状态,结束后进入就绪状态
package com.qf;
public class YourThread extends Thread{
public void run() {
for(int i=0; i<50; i++) {
try {
/*
* sleep : 让线程休眠指定时间
* 单位为毫秒 (1000毫秒=1秒)
* 休眠结束,线程进入就绪状态,才可以重新竞争cpu的资源
* 一般情况,都是模拟现实场景
*/
Thread.sleep(100); //休眠100毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName()+"----"+i);
}
}
}
-
setPriority
设置执行的优先级
优先级高的,被选中的概率就高,但不是觉得一定会被选中
package com.qf;
public class Demo04 {
public static void main(String[] args) {
/*
* setPriority(int) : 设置线程的优先级
*
*/
Thread03 t = new Thread03();
t.setName("线程1");
Thread03 t2 = new Thread03();
t2.setName("线程2");
Thread03 t3 = new Thread03();
t3.setName("线程3");
t.setPriority(10);
t2.setPriority(1);
//t3 默认为5 数值越高,被选中的概率就越高
t.start();
t2.start();
t3.start();
}
}
class Thread03 extends Thread {
public void run() {
for(int i=1; i<=100; i++) {
System.out.println(getName()+"---"+i);
}
}
}
-
setDaemon()
设置为守护线程
用户线程全部结束,守护线程就会自动结束
package com.qf;
public class Demo05 {
public static void main(String[] args) {
/*
* 守护线程
* 1. 线程可分为守护线程,用户线程
* 设置守护线程:setDaemon(true);
* 2. 在一个java进程中,如果所有的用户线程都处于终结状态,那么守护线程就主动终结
*/
Thread04 t = new Thread04();
/*
* 设置为守护线程
* 在开启之前设置
*/
t.setDaemon(true);
t.start();
for(int i=0; i<30; i++) {
System.out.println("main--"+i);
}
}
}
class Thread04 extends Thread {
public void run() {
int i=0;
while(true) {
System.out.println("守护线程---"+i);
}
}
}