发表于: 2017-05-23 21:05:13
1 1283
Task1第8天(2017年5月23日)
今日计划
继续学习夯实基础
finally代码块:定义一定执行的代码。
通常用于关闭资源
异常总结:
异常是问题的描述。将问题进行对象的封装。
异常体系
Throwable
|--Error
|--Exception
|--RuntinmeException
异常体系的特点:异常体系中所有类及监理的对象都具备可抛性
也就是说可以被throw和throws关键字所操作。
只有异常体系具备这个特点。
throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。
注意:RuntimeException除外。也就是说。函数内如果抛出RuntimeException异常,函数上可以不声明。
如果函数声明了异常。调用者需要进行处理,处理方法可以throws可以try。
异常有两种:
编译时被检测异常
该异常在编译时,如果没有处理,编译失败。
该异常被标识,代表可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的放生,建议不处理。让程序停止。需要对代码进行修正。
异常处理处理语句:
try
{
需要被检测的代码;
}
fatch()
{
处理异常的代码;
}
finally
{
一定会执行的代码;//
}
Finally:
1、通常用于关闭资源
2、只有一种情况不执行。当执行到System.exit(0);
自定义异常:
自定义类继承Exception或者RuntimeException
1、为了让该自定义具备可抛性
2、让该类具备操作异常的共性方法
当要定义自定义异常的信息时,可以使用父类已经定义好的功能
异常信息传递给父类的构造函数。
Class MyException extends Exception
{
MyException(String message)
{
Super(message);
}
}
自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。
异常的好处:
1、将问题进行封装
2、将正常流程代码和问题处理代码相分离,方便阅读。
异常的处理原则:
1、处理方式有两种:try或者throws
2、调用到抛出异常的功能时,抛出几个,就处理几个。
一个try对应多个catch
3、多个catch,父类的catch放到最下面
4、catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。
也不要不写。
当捕获到的异常,本功能处理不了时,可以继续在catch中抛出、
try
{
Throw new AExceptiom();
}
Catch(AException)
{
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常
可以将异常转换后,再抛出和该功能相关的异常。
或者异常可以处理,当需要将该异常产生的和本功能相关的问题提供出去。
让调用者知道,并处理。也可以将捕获异常处理后,转换新的异常抛出
try
{
Throw new AExceptiom();
}
Catch(AException)
{
//对AException处理
throw new BException();;
}
异常注意事项:
在子父类覆盖式:
1、子类抛出的异常必须是父类的子类或者子集
2、如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛
包packge:
1、很多对文件进行分类管理
2、给类提供多层命名空间
3、卸载程序文件的第一行
4、类名的全程是 包名.类名。
5、包也是一种封装形式。
包与包之间进行的访问,被访问的包中的类以及类中的成员,需要public修饰
不同包中的子类还可以直接访问父类中被protected权限修饰的成员。
包与包之间可以使用的权限只有两种public protected
public protected default private
同一个类中 ok ok ok ok
同一个包中 ok ok ok
子类 ok ok
不同包中 ok
多线程
进程:是一个正在执行中的程序
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:是一个进程中的一个独立的控制单元
线程在控制着进程的执行。
一个进程中至少有一个线程。
如何在自定义的代码中,自定义一个线程?
1、继承Thread类并重写 Thread 类的 run 方法。
步骤:
1、定义类继承Thread;
2、复写Thread类中的run方法
3、调用线程的start方法
static Thread currentThread():获取当前线程对象。
GetName():获取线程的名称
设置线程名称:setName或者构造函数
创建线程的第二种方式:实现Runnable()接口
步骤:
1、定义实现Runnable接口
2、覆盖Runnable接口中的run方法
将线程要运行的代码存放在该run方法中
3、通过Thread类建立线程对象。
4、将Runnable结构的子类对象作为实际参数传递给Thread类的构造函数
自定的run方法所属的对象是Runnable接口的子类对象。
要让线程去执行指定对象的run方法。就必须明确该run方法所属的对象。
5、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
实现方式和继承方式有什么区别?
实现方式好处在于:避免了单继承的局限性。
在定义线程时,建议使用实现方式。
两种方式的区别:
继承Thread:线程代码存放在Thread子类run方法中
实现Runnable,线程代码存在接口的子类的run方法中
多线程同步代码块
Java对于多线程的安全问题提供了专业的解决方式。
就是同步代码块
Synchronized(对象)
{
需要被同步的代码
}
对象如同锁,持有锁的线程可以在同步中执行
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步前提:
1、必须要有两个或者两个以上的线程
2、必须是多个线程使用同一个锁
必须保证同步中只能有一个线程在运行。
好处:解决了多线程的安全问题。
弊端:多个线程需要判断锁,较为耗资源。
同步的另一种方法,同步函数,将synchronized作为修饰符放函数上。
同步函数使用的锁是this
如果同步函数被静态修饰后,使用的锁是该方法所在类的字节码文件对象。类名.class
单例设计模式
懒汉式 加同步
class Single
{
private static Single s= null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized (Single.class)
{
if(s==null)
s = new Single();
}
}
return s;
}
}
注意:运用同步需要避免死锁。
死锁:
package ten;
class Test1 implements Runnable
{
private boolean flag;
Test1(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
synchronized (MyLock.locka)
{
System.out.println("if locka");
synchronized (MyLock.lockb)
{
System.out.println("if lockb");
}
}
}
else
{
synchronized (MyLock.lockb)
{
System.out.println("else lockb");
synchronized (MyLock.locka)
{
System.out.println("else locka");
}
}
}
}
}
class MyLock
{
static Object locka = new Object();
static Object lockb = new Object();
}
public class DeadLockTest
{
public static void main(String[] args)
{
Thread t1 = new Thread(new Test1(true));
Thread t2 = new Thread(new Test1(false));
t1.start();
t2.start();
}
}
收获
复习总结了一下异常相关知识,finally,try catch语句;
学习了package相关知识,以及多线程的两种方法,继承,实现,
同步代码块,同步函数,死锁。
评论