异常与多线程

异常:

异常:是程序中出现的无法避免的问题。按照面向对象思想进行描述封装成对象(即:问题对象)。

 

异常体系:将异常进行分类并提取共性而形成的体系。其中父类为:Throwable,即所有异常都是具有可抛出的性质的。 有两个已经定义的子类Error,即错误,通常是由jvm发生的问题,或程序外部的环境导致的问题,是需要对程序进行修正而不是对代码进行处理;另外一个是Exception,即异常,可以有针对性的处理方式。在Exception中又有两个子类:unchecked Exception (RuntimeException),即未检测异常和Checked Exception (除RuntimeException外),已检测异常。

 

Eg:

IndexOutOfBoundsException;

NullPointerException;

ClassCastException;

1、CurrentConnetionException。

 

注意:

1, 这个体系中的所有类和对象都具备可抛性(即:该体系的类和对象都可以被throws和throw操作)。

2, 都以父类名才作为子类的后缀名。

 

出现问题后,针对问题只可抛出或者捕捉。

 

抛出:throw和throws

可抛性:把将可能出现的问题抛出正在运行的函数让调用者去处理。

 

格式:

throws 异常类名,异常类名   

注释:可抛出多个类名字,标示在函数上。需要调用者对该异常进行处理。对于不需要调用者处理的,即运行时才会发生的异常,程序停止,由调用者对代码进行修正。

 

throw 异常类对象;     

注释:标示在问题出现的函数内部,只可一下标一个。编译被检查的异常在函数内被抛出,函数必须要声明,否编译失败。

 

Eg:

Public void door(String...a) throwsIndexOutOfBoundsException,ClassCastException

{

    a[x];

    if(x>50)

    {

        throw new IndexOutOfBoundsException();

}

… …

}

 

函数内容如果有throw异常对象,且没有进行处理,那么函数上一定要throws,否则编译失败,但是对于unchecked Exception可以不用标示throws。

 

捕捉

格式:

try

{

    被捕捉的代码端,放入可能会出现问题的代码及相关代码;

}

catch(异常类 变量名)

{

    异常处理代码;

}

Finally

{

    一定会执行到的代码,对于关闭用户有限的资源很有用。

当前面出现System.exit(0),即虚拟机退出命令时,这块不会执行。

}

 

三种格式:

3,

try

finally

 

2,

try

catch

 
1,

try

catch

finally

 

Eg:

         try{

                            car1.door(x);

                            System.out.println(x+“号门开”);       

                   }

                   catch(nulldoor e){

                            System.out.println(“无此门”);

                   }

                   catch(doorinopen e){

                            System.out.println(”门是开的”);

                   }

 

Try or throws

功能内部如果出现可以被处理的异常用try;否则用throws。

 

自定义异常:针对未定义过的异常进行封装成自定义异常。当出现的异常是调用者处理不了的,可以通过自定义异常将此异常转换为一个调用者可以处理的异常抛出。

 

自定义异常的方法:定义一个子类继承Exception或RuntimeException,让该类具备可抛性。。

 

异常在继承中需要注意:

当父类无异常时子类的覆盖的方法中出现了异常,只能try不能throws;

当父类有异常时子类只能抛出父类的同异常或子异常;

当异常子类无法处理且影响了子类方法的具体运算,子类可以通过抛出RuntimeException异常或者其子类。

 

多线程:

进程:正在进行中的程序,负责应用程序的空间的标示。

线程:进程中一个程序执行控制单元,一条执行路径,负责应用程序的执行顺序。

 

基础:

1,Cpu的在不同线程中的快速切换,被切换到的线程具有执行权。

2,在jvm开启时,最开始建立的是主线程(main方法)。在jvm运行时垃圾回收器线程作为守护线程负责垃圾回收。当只有守护线程时候程序终止。

3,至少有一个线程,当有多个线程时,每个线程有自己独自的执行空间,方法区与变量。

4,线程要运行的代码都统一存放在了run方法中。通过覆盖run方法创建自己的线程。

5,线程名称:Thread-编号。编号从0开始。返回当前线程的名称的方法为:Thread.currentThread().getName()

 

创建线程两方法:

继承Thread ,由子类覆写run方法。

Eg:

定义类继承Thread类;

classnewThread extends Thread

{

     run() //复写run方法,让线程运行的代码都存放到run方法中

{

    。。。。。。

}

 

}

 

Public static voidmain(String[] args)

{

    new newThread().start(); //创建Thread类的子类对象,创建线程对象, 调用线程的start方法,开启线程,并执行run方法

}

 

实现一个接口Runnable

Eg:

class newThread implementsRunnable//定义类实现Runnable接口。

 

{

        run() //复写run方法,让线程运行的代码都存放到run方法中

{

    。。。。。。

    }

}

通过Thread类创建线程对象;

    Public static void main(String[]args)

{

/*将实现了Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数以明确要运行的run方法所属的对象。调用Thread对象的start方法。开启线程,并运行Runnable接口子类中的run方法。*/

new Thread(new newThread()).start();

}

 

注释:Runnable接口将线程要执行的任务封装成了对象。实现Runnable接口可以避免单继承的局限性。

 

线程五状态:

被创建:start()

运行:具备执行资格,与执行权;

冻结:针对运行的线程被调用sleep(time),wait()时进入的状态,线程释放了执行权,与执行资格;

临时阻塞状态:线程具备cpu的执行资格,但是没有cpu的执行权;处于cpu可以切换但是没有被切换到的状态。

消亡:stop()后,或者线程运行结束

 

安全问题:

当同一段语句在被一个线程执行时还没有执行完就被其他线程执行了的时候将可能导致安全问题的发生。为了避免问题发生,要对那段语句进行同步化,即任何时刻只能一个线程对其进行读取操作。

解决问题的同步方法方式:

同步代码块:

格式:

synchronized(对象) //对象就是锁,可是是任意的对象。

    需要被同步的代码;

}

 

同步函数:将同步关键字定义在函数上。

    格式:

    Public synchronizeddoor()  //锁为this

 

{

    需要被同步的代码;

}

 

注意: 静态同步函数的锁是:类名.class, 即该类的字节码文件对象

 

锁的引入导致可能会出现的新的问题:

同步死锁:当同步进行嵌套时,比如同步函数中有同步代码块,同步代码块中还有同步函数可以看到的程序暂停运行的状态。

 

线程间通信:思路:多个线程在操作同一个资源,但是操作的动作却不一样。

1:将资源封装成对象。

2:将线程执行的任务(任务其实就是run方法。)也封装成对象。

 

 

等待唤醒机制:

唤醒机制能够改变线程的状态,由冻结到阻塞,或相反。

Wait():将同步中的线程进入冻结状态,进入线程池。可以指定时间也可以不指定时间,当不指定时间时,只能由notify或notifyAll来唤醒。

Notify():唤醒线程池中某一个等待中的线程。

notifyAll():唤醒的是线程池中的所有线程。

 

注意:

1:因为这些方法必须要标示所属的锁,所以这些方法都需要定义在同步中才有意义。

2:因为这三个方法都需要定义在同步内被锁调用,而锁又可以是任意对象,所以这三个方法都定义在Object类中。

 

Lock接口( JDK1.5版本):

Lock:将锁封装成了对象。实现了锁的独立性,让对锁的操作更加灵活与独立。

Condition接口:具有直接操作等待唤醒的方法 await()、signal()、signalAll()。

 

Eg:

class BoundedBuffer {

   final Lock lock = newReentrantLock();

   final ConditionnotFull  = lock.newCondition();

   final ConditionnotEmpty = lock.newCondition();

   final Object[] items =new Object[100];

   int putptr, takeptr,count;

   public void put(Objectx) throws InterruptedException {

     lock.lock();

     try {

       while (count ==items.length)

         notFull.await();

       items[putptr] = x;

       if (++putptr == items.length) putptr = 0;

       ++count;

       notEmpty.signal();

     }

    finally {

       lock.unlock();

     }

   }

   public Object take()throws InterruptedException {

     lock.lock();

     try {

       while (count == 0)

         notEmpty.await();

       Object x =items[takeptr];

       if (++takeptr ==items.length) takeptr = 0;

       --count;

       notFull.signal();

       return x;

     }

finally {

       lock.unlock();

     }

   }

 }

 

其他方法:

sleep:指定线程冻结时间使线程冻结,当时间到自动从冻结状态转成临时阻塞状态。线程会释放执行权,但不是不释放锁。

Interrupt():将冻结状态清除,让线程进入临时阻塞状态。

Stop:停止线程(过时)。现在通过结束run方法内循环break a来停止线程。如果线程处于了冻结状态,是不可能读到标记的,用Interrupt即可。

setPriority(int newPriority):改变线程的优先级。

getPriority():获取线程的优先级。

Thread.yield():暂停当前正在执行的线程对象,并执行其他线程。

setDaemon(true):将该线程标记为守护线程或用户线程,当所有线程都是守护线程时程序结束。

join:临时加入调用的线程,且要一直运行到此线程结束时用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值