异常、线程

异常
概念:java

指的就是程序在执行过程当中,出现的非正常的状况,最终会致使JVM的非正常中止

异常体系:程序员

java.lang.throwable : 异常的顶级

子类:安全

1.Exception   表示异常,异常产生后程序员能够经过代码的方式纠正,使程序继续运行,
                        必需要处理的.
  2.Error 严重那个错误Error,没法经过处理的错误只能事先避免,
经常使用方法:
1. public void printStackTrace():打印异常的详细信息
     包含了异常的类型,异常的缘由,还包括异常出现的位置,在开发和调试阶段,都得使用
       printStackTrace.
2.public String getMessage(): 获取发生异常的缘由
        提示给用户的时候,就提示错误缘由,
  3.public String toString(); 获取异常的类型和异常描述信息(不用)
分类:
  1. 编译时期异常: checked异常,在编译时期,就会检查,若是没有处理异常,则编译失败(如
      日期格式化异常)
     举例:ArrayIndexOutOfBoundsException
           NullPointerException
             ClassCastException
             IndexOutOfBoundsException
           ConcurrenModificationException
  2. 运行时期异常: runtime异常,在运行时期,检查异常,在编译时期,运行异常不会编译器检
     测 (不报错).(如数学异常)
     举例: FileNotFoundException
              IoException
            ParseException
              
        异常的产生过程解析

工具类:
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public class ArrayTools{
public static int getElement(int[] arr, int index) {多线程

int element = arr[index];
return element;

}
}
测试类:
[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
public class ExceptionDemo {
public static void main(String[] args){并发

int[] arr = ArrayTools.getElement(arr, 4)
System.out.println("num=" + num);
System.out.println("over");

}
}
图解:ide

第二章 异常的处理工具

关键字: try, catch, finally, throw, throws
      throw
           用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法执行.
      格式:
           throw new 异常类名(参数);
      throws
      概念:
        声明异常,将问题标识出来,报告给调用者,若是方法内用过throw抛出了编译时异常,而没有
          捕获处理,那么将经过throws进行声明,让调用者去处理,,,,,,用在方法声明之上,用于表示当
         前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).
      格式:
          修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2...{  }
     try....catch
    概念: 捕获异常
        try:该代码块中编写可能产生异常的代码。
                try异常
              最后只会抛出一个异常
                若是没有捕获到
                交给java虚拟机
          catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理
                     在开发中也能够在catch将编译器异常转换成运行期异常处理
                     若是异常出现的话,会马上终止程序,若是不想程序终止,因此咱们得处理异常:
                1. 该方法不处理,而是声明抛出,由该方法的调用者来处理(throws)。
                2. 在方法中使用try-catch的语句块来处理异常。
     语法格式:

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
try{
编写可能会出现异常的代码
} catch(异常类型 e) {
处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}测试

异常使用捕获处理的三种方式:
        1.多个异常分别处理
        2.多个异常一次捕获,屡次处理 (经常使用方式)
        3.多个异常一次捕获一次处理
   finally 代码块
         有一些特定的代码不管异常是否发生,都须要执行,finally代码块中存放的代码都是必定会被
         执行. ......当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,不然
         finally永远会执行

异常注意事项:this

1.运行时异常被抛出能够不处理,即不捕获也不声明抛出
2.若是父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集
3.父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常,此时子类产生该异常,
   只能捕获处理,不能声明抛出
4.当多异常处理时,捕获处理,前边的类不能是后边类的父类
5.在try/catch后能够追加finally代码块,其中的代码必定会被执行,一般用于资源回收
6.若是finally有return语句,永远返回finally中的结果,避免该状况

第三章 自定义异常类线程

定义:
     1.自定义一个编译器异常:自定义类 并继承于java.lang.Exception
   2.自定义一个运行时期的异常,:自定义类并继承于java.lang..RuntimeException.
       处理自定义异常类:
           throws 自定义异常类类名
           try catch(自定义异常类类名 变量)

第四章 多线程

并发:
       (交替执行)指两个或多个事件在"同一时间段内"发生
 并行:
        (同时执行) 指两个或多个事件在"同一时刻"发生(同时发生)
 进程:
       内存中运行的一个应用程序.
       每一个进程都有一个独立的内存空间,一个应用程序能够同时运行多个进程.
       进程也是程序的一次执行过程,是系统运行程序的基本单位
       系统运行一个程序便是一个进程从建立,运行到消亡的过程.
线程:
      是进程内的一个独立执行单元(一条代码执行路径)
      一个程序运行后至少有一个进程,一个进程中能够包含多个进程
多线程的好处:
      效率高
      多个线程之间互不影响
   
线程的调度:
      多个线程要并发执行,那个线程被执行,那个线程不被执行,就是调度.
方式:
      1.分时调度:全部线程轮流使用CPU,平分占用CPU的时间
      2.抢占式调度:优先让优先级高的线程使用CPU;若是优先级相同,则随机选择一个
       线程执行.

Java使用的是"抢占式"调度.
主线程:

咱们之前写的代码,也在一条线程中执行,该线程叫作"main线程",也成为"主线程.
   若是没有额外建立线程,那么程序就只有一个线程,即主线程,此时程序是"单线程"
     的单线程的执行特色;

同一个线程内的代码,从上往下一次执行.

建立多线程程序的第一种方式: 继承Thread类

实现多线程的第一种方式:
           1.定义类,继承Thread类
           2.重写run()方法,run方法内部是线程要执行的任务
           3.建立Thread子类的对象,调用start()方法启动线程
       java.lang.Thread类 : 表示线程,事项了Rannable接口
       void start():启动线程,即让线程开始执行run()方法中的代码
   注意:
       必须调用start() 方法来开启线程,不能直接调用run() 方法,调用run()会变成
       单线程同一线程对象,不能屡次调用start()方法
       Java是抢占式调度,不一样线程的代码,执行顺序是随机的

第六天 线程、同步
第一章 线程

一、Java线程调度是抢占式的,多个线程互相抢夺CPU的执行权。CPU执行哪一个线程是随机的
  二、多线程状况下,每一个线程都有各自的栈内存。
  三、Thread类:表示线程,实现了Runnable接口

经常使用方法:
构造方法
[Java] 纯文本查看 复制代码
?
1
2
3
4
Thread(): 建立Thread对象
Thread(String threadName): 建立Thread对象并指定线程名
Thread(Runnable target): 经过Runnable对象建立Thread对象
Thread(Runnable target, String threadName)
成员方法
[Java] 纯文本查看 复制代码
?
1
2
3
4
void run(): 用于子类重写,表示线程执行任务,不能直接调用
void start(): 启动线程,让线程开始执行run()方法中的代码
String getName(): 获取线程的名称
void setName(String name): 设置线程名称
静态方法
[Java] 纯文本查看 复制代码
?
1
2
static Thread currentThread(): 返回对当前正在执行的线程对象的引用
void sleep(long mills): 让所在线程睡眠指定的毫秒
建立线程方式二:实现Runnable接口

定义Runnable接口实现类,重写run方法
    建立Runnable实现类对象
   建立Thread类对象,在构造方法中传入Runnable实现类对象
   经过Thread对象调用start()方法启动线程

Thread和Runnable的区别

实现Runnable的好处:
    一、避免单继承的局限性
    二、加强了程序的扩展性,下降了程序的耦合性
       (线程是Thread,任务是Runnable实现类对象,至关于将线程和任务分离)

匿名内部类方式建立线程

new Thread(new Runnable){
      重写run()
 }

线程安全问题

发生场景:多个线程操做共享资源
   问题发生缘由:
       JVM是抢占式调度,CPU在每一个线程之间切换时随机的,代码执行到什么位置是不肯定的。
      在操做共享资源时,一个线程还没执行完,另外一个线程就来操做,就会出现问题
   解决多线程操做共享数据的安全问题
       3种方式:同步代码块
       同步方法
       锁机制
       同步代码块:使用synchronized关键字修饰的代码块,并传入一个看成锁的对象格式:

[Java] 纯文本查看 复制代码
?
1
2
3
synchronized(锁对象) {
//操做共享数据的代码
}

注意:锁对象能够是任意类型的一个对象
           锁对象必须是被多个线程共享的惟一对象
  锁对象的做用:只让一个线程在同步代码块中执行
  同步的原理:
       线程进入同步代码块前,会争夺锁对象,只有一个线程会抢到
       进入同步代码块的线程,会持有锁对象,并执行代码块中的代码
       此时同步代码块外的线程处于阻塞状态,只能等待
       同步代码块内的线程执行完代码块,会离开同步代码块,并归还锁对象给同步代码块
       此时同步代码块外的其余线程就能够继续争夺锁对象

同步方法:

非静态同步方法:(具备默认锁对象:this)

[Java] 纯文本查看 复制代码
?
1
2
3
public synchronized void method() {
//可能会产生线程安全问题的代码
}

静态同步方法

[Java] 纯文本查看 复制代码
?
1
2
3
public static synchronized void method() {
//可能会产生线程安全问题的代码
}

静态同步方法的锁对象:当前类的字节码对象
  获取一个类的字节码对象的3种方式:
    一、对象.getClass
   二、类名.class
   三、Class.forName(“类的全路径”)
  Lock锁
   成员方法:

[Java] 纯文本查看 复制代码
?
1
2
void lock(): 获取锁
void unlock(): 释放锁
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
public class RunnableImpl implements Runnable {
Lock lock = new ReentrantLock();
@override
public void run() {

lock.lock(); //加锁
try{
  //操做共享变量的代码
} finally {
  lock.unlock(); //在finally中保证释放锁
}

}
}
线程安全和效率的特色

程安全,效率低
  线程不安全,效率高

线程的状态

锁对象,也称为“同步锁”,“对象监视器”

Object类中关于线程的方法:

成员方法:

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
void notifyAll(): 唤醒全部在同一个锁对象上处于等待状态的线程
void wait(): 让当前线程处于无限等待状态
void wait(long timeout): 让当前线程处于计时等待状态,时间到或被唤醒后结束此状态
void wait(ling timeout, int nanos): 让当前线程处于计时等待状态,时间到或被唤醒后结束此状态
线程的生命周期的6种状态:
一、NEW新建

线程被建立,但没有调用start()启动

二、RUNNABLE可运行

调用start()方法后已启动,但可能正在执行run()方法的代码,也可能正在等待CPU的调度

三、BLOCKED阻塞

线程试图获取锁,但此时锁被其余线程持有

四、WAITING无限等待

经过锁对象调用无参的wait()进入此状态
  等待其余线程经过锁对象执行notify()或notifyAll()才能结束这个状态

五、TIMED_WAITINGj计时等待

如经过锁对象调用有参的wait(long millis)或sleep(long millis),则进入此状态
  直到时间结束以前被其余线程经过锁对象执行notify()或notifyAll()唤醒,或时间结束自动唤醒

六、TERMINATED终止

run()方法结束(执行结束,或内部出现异常),则进入此状态

Object类成员方法:[Java] 纯文本查看 复制代码?12void notifyAll(): 唤醒全部在同一个锁对象上处于等待状态的线程void wait(long timeout): 让当前线程处于计时等待状态,时间到或被唤醒后结束此状态

相关文章
相关标签/搜索