第八章 异常处理与多线程Word格式.docx
- 文档编号:397685
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:35
- 大小:215.62KB
第八章 异常处理与多线程Word格式.docx
《第八章 异常处理与多线程Word格式.docx》由会员分享,可在线阅读,更多相关《第八章 异常处理与多线程Word格式.docx(35页珍藏版)》请在冰点文库上搜索。
(1)j3_28.java–使用try…catch….finally语句捕获数组下标越界异常并处理异常对象(也称运行时异常RuntimeException)
classTest{
try{//选定捕获异常范围
i++)//试图访问不存在的元素
{
//catch语句需要一个形参,指明捕获异常类型对象,异常发生时程序执行catch体内的语句.
catch(Exceptione)
System.out.println(e);
}
finally{//无论异常是否发生finally体内的语句总是被执行
It'
sok!
"
System.out.println("
OutofTry!
(2)ExceptionTest3.java-非运行时异常(编译器编译时发生的异常-Java编译器从语法上要求对异常事件做出处理,否则不能通过编译)
例如:
ExceptionTest3.java-不能通过编译,改正为ExceptionTest4.java就可编译。
importjava.io.*;
publicclassExceptionTest3{
//创建字节输入流对象
FileInputStreamin=newFileInputStream("
myfile.txt"
intb;
b=in.read();
//读文件
while(b!
=-1)
System.out.print((char)b);
in.close();
ExceptionTest4.java-(文件不存-非运行时异常)-(使用try…catch….finally语句捕获并处理异常对象)
publicclassExceptionTest4{
try{//try{….}语句块选定捕捉异常的范围,如执行的语句块有异常则抛出异常对象
FileInputStreamin=newFileInputStream("
//执行的语句块
intb;
b=in.read();
while(b!
=-1){
System.out.print((char)b);
b=in.read();
}
in.close();
catch(IOExceptione){//异常对象被抛出将被catch(IOExceptione)语句捕获,异常对象作为参数传入,捕获异常对象有有多种,也就是可有多个catch语句,此时为IOExceptione,
//输出异常信息
finally{//善后语句无论try{….}语句是否发生异常finally语句都会执行
(3)j3_29.java–使用throws语句声明抛出异常对象给调用方用的catch()方法捕获异常并处理异常
publicstaticvoidmain(String[]args){
Testt=newTest();
try{
t.readFile();
//调用readFile()方法(在调用方readFile()方法中的catch()方法中捕获到这个异常并处理)
catch(IOExceptione){
System.out.println(e);
System.out.println("
退出!
//在readFile()方法中声明IOException异常对象,异常发生时该方法并不进行异常处理,而是抛出异常对象给调用方readFile()方法处理,.
publicvoidreadFile()throwsIOException{
//myfile.txt文件不存在
System.out.print((char)b);
b=in.read();
(4)Testthrow1.java---手工抛出异常
publicclassTestthrow1{
staticvoidreadArray(inta,intb){//静态读数组方法
//如果a<
b手工抛出数组下标越界异常对象并调用捕捉异常方法输出异常提示
try{
if(a<
b)
//抛出数组下标越界异常对象并在readArray方法中的catch捕获输出很可惜超过数组范围!
信息
thrownewArrayIndexOutOfBoundsException("
很可惜超过数组范围!
else
{intarray[]=newint[a];
//创建数组长度为a的整型数组
array[b]=11;
//在下标号为4位置处赋值11给数组
数组赋值成功!
}}
catch(ArrayIndexOutOfBoundsExceptione)
{System.out.println("
readArray方法异常提示:
+e.getMessage());
throwe;
}//throwe抛出错误给调用方及main方法的readArray(4,6)方法的catch捕获
//调用readArray(6,4)静态方法并传递参数a=6,b=4,执行else后语句为数次组合法赋值
readArray(6,4);
readArray(4,6);
}//数组元素为4即长度为4,下标为6数组下标越界异常
catch(ArrayIndexOutOfBoundsExceptione){
main方法异常提示:
(5)j3_30.java---自定义抛出异常类
classMyExceptionextendsException{
privateintidnumber;
//声明整型变量idnumber代表出错代码
publicMyException(Stringmessage,intid){//声明MyException()异常方法
super(message);
//返回父类信息
this.idnumber=id;
//MyException对象出错id为3代表注册人数为负值,不合理
publicintgetId(){//getId()方法,取得出错Id
returnidnumber;
//在regist(intnum)方法中声明MyException异常,并抛出异常对象
publicvoidregist(intnum)throwsMyException{
if(num<
0){//注册人数<
0
//抛出异常对象newMyException("
人数为负值,不合理"
3);
参数传到MyException()方法中设置出错种类为3并取得错误代码3,同时将抛出异常对象给调用方的catch捕获输出异常原因即登记失败,出错种类3
thrownewMyException("
}
登记人数"
+num);
publicvoidmanager(){//管理注册方法
try{
//设计错误及注册人数-100在调用regist(intnum)方法时满足抛出异常对象,并执行catch语句
regist(-100);
}catch(MyExceptione){
System.out.print("
登记失败,出错种类:
+e.getId()+"
\n"
System.out.print("
本次登记操作结束"
publicstaticvoidmain(Stringargs[]){//main()入口
Testt=newTest();
t.manager();
8.2多线程(java中引入多线程机制的目的在于实现多任务,以提高程序利用CPU的效率.主要通过多线程之间共享代码和数据来实现的.)
多线程是根据多任务的原理,在一个程序内部实现多个任务(顺序控制流)的并发执行.其中的每个任务被称为线程(Thread),线程是一个程序内部的顺序控制流.
(1)进程–执行一个程序的过程(包括分配内存﹑外设等资源﹑等侯处理器的执行程序中的指令﹑程序执行完后系统回收所分配资源的过程),每个进程有自己的内存空间和资源﹑进程之间不会共享系统资源,进程切换开销大。
(2)线程-线程是比进程更小的运行单位,一个进程可划分成多个线程。
线程由操作系统调度独立执行控制,和进程的区别是没有独立的存储空间,而是和所属进程的其它线程共享一个存储空间,即共享进程资源,所以线程之间数据通信交换比进程切换快。
(3)每个Java程序都有一个默认主线程,这个主线程从main方法开始并负责执行main方法。
在main方法的执行中再创建的线程称为其他线程,如果main方法的执行中没有创建其他线程,那么main方法执行完最后一条语句,及main方法返回时,JVM就会结束Java应用程序,如果main方法中再创建了其他线程,那么JVM就会在主线程和其他线程之间轮流切换,保证每个线程都有机会使用CPU,直到JVM执行完所有线程才会结束Java应用程序。
因此通过多线程技术可提高CPU的使用效率和多程序的并发执行,完成多任务。
(4)线程随着程序的运行而产生,随着程序的结束而消亡.每个线程都存在一个从新建,运行到死亡的生命周期.在生命周期中,一个线程具有新建,就绪,运行,阻塞和终止5种状态。
【例9.1】Example9_1.java
publicclassExample9_1
{publicstaticvoidmain(Stringargs[])
{Lefthandleft;
Righthandright;
left=newLefthand();
//创建左线程
right=newRighthand();
//创建右线程
left.start();
//左线程开始
right.start();
//右线程开始
for(inti=1;
=6;
i++)
{System.out.println("
我是主线程"
}
classLefthandextendsThread
{publicvoidrun()
{for(inti=1;
=9;
{
我是左手线程"
classRighthandextendsThread
我是右手线程"
8.3线程的基本概念
每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体.
8.4线程实现的两种方法
(1)使用Thread类的子类方法创建线程步骤
1.定义一个类继承Thread类,重写Thread类中的run()方法
2.创建该Thread子类的对象
3.调用该对象的start()方法时,run()方法将被自动调用,线程启动.
【例8-1】j3_39.java---用Thread类的子类方法创建线程
classTestThread3{
publicstaticvoidmain(Stringargs[]){
//
(2)创建该Thread子类的对象,即是创建一个线程(或是创建了一个虚拟的CPU)
Threadt=newRunner3();
t.start();
//(3)调用该对象的start()方法时,run()方法将被自动调用线程被启动
classRunner3extendsThread{//
(1)定义一个子类Runner3继承Thread类
publicvoidrun(){//线程体(重写Thread类中的run()方法)
i<
30;
i++){//线程对象运行
No."
+i);
结果:
No.0~No.29
此方法直接继承Thread类创建线程时,Thread类的子类Runner3无法从其他类继承,run()方法的当前对象就是线程对象,可直接操纵.这种方法简单.java中只允许单继承,限制了类的自由,浪费了类的资源,因此采用继承Thread类来创建线程不是最好的方法.
(2)实现Runnable接口创建多线程步骤
运行线程的另一种方法是实现Runnable接口,然后生成运行这个类的线程即可.Runnable接口是定义在java.lang包中的一个接口,其中只提供了一个抽象的run()方法,即线程体.
1.定义一个类实现Runnable接口,重写其中的run()方法.
2.创建Runnable接口实现类的对象.
3.创建该Thread类的对象(以先前Runnable类型对象为构造方法实参)
4.调用Thread对象的start()方法时,run()方法将被自动调用,启动线程.
【例8-2】j3_38.java---用Runnable接口创建多线程
classTestThread2{
publicstaticvoidmain(Stringargs[]){
//2.创建Runnable接口实现类的对象r
Runner2r=newRunner2();
//3.创建该Thread类的对象(以先前Runnable类型对象r为实参),共创建两个线程t1,t2
Threadt1=newThread(r);
Threadt2=newThread(r);
t1.start();
//4.调用Thread对象的start()方法时,run()方法自动运行,启动2个线程.
t2.start();
//1.定义Runner2类实现Runnable接口,重写其中的run()方法.
classRunner2implementsRunnable{
publicvoidrun(){//重写run()方法
20;
i++){
//用Thread类的静态方法Thread.currentThread()取得当前正在执行的线程对象,并通过它的getName()方法获得线程名.
Strings=Thread.currentThread().getName();
System.out.println(s+"
:
"
在本例中创建了两个新线程t1,t2,它们共享Runner2()类中的run()方法,同时也共享创建Runnable接口实现类的对象r,两个线程t1,t2在运行中分别操纵对象r调用其重写run()方法.其结果线程t1,t2作为独立的顺序控制流,并发地交替执行,如果线程t1因某种原因处于阻塞状态,如等待用户键盘输入,CPU会立即转到线程t2执行,依此类推,而不必空置CPU.
使用Runnable接口创建线程时,可以将CPU,代码和数据分开,形成清晰的模型.线程体.
run()方法所在的类还可从其它类继承一些有用的属性和方法,保持程序风格一致性.
【例9.1】Example9_3.java
publicclassExample9_3
{publicstaticvoidmain(Stringargs[])
{Bankbank=newBank();
//创建银行对象
//线程的目标对象设置被线程共享的money
bank.setMoney(300);
//存300元钱到银行中
bank.会计.start();
//线程对象会计开始记帐
bank.出纳.start();
//线程对象出纳开始支付
classBankimplementsRunnable//声明银行类实现Runnable接口
{privateintmoney=0;
Thread会计,出纳;
//声明线程对象会计,出纳
Bank()//构造函数
{会计=newThread(this);
//创建线程对象会计
会计.setName("
会计"
//设置线程名会计
出纳=newThread(this);
//创建线程对象出纳(会计和出纳线程的目标对象相同)
出纳.setName("
出纳"
//设置线程名出纳
publicvoidsetMoney(intmount)//存钱方法
{money=mount;
//存300元
publicvoidrun()//接口中的方法(线程体)
{while(true)
{money=money-50;
//money=300-50=250
if(Thread.currentThread()==会计)
我是"
+会计.getName()+"
现在有:
+money+"
元"
if(money<
=150)
{System.out.println(会计.getName()+"
进入死亡状态"
return;
//如果money少于150,会计的run方法结束,会计线程进入死亡方法
elseif(Thread.currentThread()==出纳)
+出纳.getName()+"
=0)
//如果money少于0,出纳的run方法结束,出纳线程进入死亡方法
try{Thread.sleep(800);
//让线程休眠800毫秒
catch(InterruptedExceptione){}
【例8-3】TestThread1.java-
classTestThread
{staticAThreadaThread;
staticBThreadbThread;
publicstaticvoidmain(Stringargs[])
{aThread=newAThread();
//创建两个线程类对象AThread﹑BThread。
bThread=newBThread();
aThread.start();
//起动线程
bThread.start();
classAThreadextendsThread//声明AThread类
{
publicvoidrun()
for(inti=0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第八章 异常处理与多线程 第八 异常 处理 多线程