Java 线程Thread详解

在Java中,实现多线程的类是 Thread 类。

定义Thread对象有两种方法,一种是直接继承Thread,另一种是实现Runable接口。两者都需要写 run 方法。

而且,无论是哪一种方法,生成的线程都是 Thread。也就是说,其实线程类只有一种,那就是Thread。

 

线程也有自己的状态,除了新建,就绪,运行,等待/阻塞,死亡

这些状态可以转换。线程个状态的转换是:就绪可以进入运行,运行也可以进入就绪;运行还可以进入等待/阻塞;

但是等待/阻塞不能进入运行,等待/阻塞可以进入就绪状态。

 

# 新建 :就是利用Thread的构造函数定义一个线程,从此,线程的生命开始了。

# 就绪 :当执行了Thread中的strat方法,及使得线程进入就绪状态,随时可以进入运行状态。

# 运行 :当操作系统的调度器把CPU分给了这个线程,这个线程就进入了运行状态,

         也就是执行我们在线程中定义的run方法里面的内容。

# 等待/阻塞

   1. 当一个线程的继续执行需要一个条件,但是该条件还不成熟,需要调度器来通知。

      而等待调度器发出通知的这段时间内,线程就进入了等待状态。

   2. 当一个线程访问一个资源的时候,这个资源正被另外的线程访问,而这个资源是加了锁的,

      之允许一个线程访问。这时候,线程就进入了阻塞状态。

# 死亡:当线程的run方法运行完之后,线程死亡,这是正常死亡;

         当线程方发生异常而没有捕获时,也会死亡,这是非正常死亡。

     不管是正常死亡还是非正常死亡,都是死亡

下面是一些重要属性:

 * 优先级:每个线程都有自己的优先级 。

      Java中的线程有10个优先级。但是结合操作系统来说,每个操作系统的线程优先级的数量各不相同。

      所以,Java提供了三个常量,分别是MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY。

 * 守护属性 :如果线程被标志为守护属性,那么这个线程就是守护线程 。

      守护线程不能阻止程序(进程)的退出,只要没有主线程,程序就结束,

而不管守护线程的运行状态。所以,我们一般不在守护线程中做一些主要工作。

设置线程的守护属性函数为:setDaemon(true)

 * 异常处理:如果线程抛出的异常没有被捕获,线程就会死亡。这就意味着,在设计线程时,要重视捕获异常。

但是,如果没有捕获异常,或者出现了一个异常没有捕捉到,是不是线程就马上死亡呢?

当然不是。线程有一个重要的属性,就是未捕获的异常处理器 。

使用这个方法设置:setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

如果设置了这个属性,就表示如果有异常没有被捕获,那么就会启动这个处理器来处理这个异常,

       这样,就加强了我们都线程的处理能力。

UncaughtExceptionHandler是一个接口,我们需要实现unCaughtException(Thread t, Throwalbe e)方法。

如果我们忘了为每个线程设置UncaughtExceptionHandler的时候,是不是线程抛出为捕获的异常时,就会死亡呢?

答案是否定的。当线程抛出未捕获的异常时,而线程又没有设置处理器时,怎么办呢?

这时候,那么这时候的为捕获的异常处理器就变成了ThreadGroup,就是线程组(什么是ThreadGroup,等会再说)。

因为线程组实现了 UncaughtExceptionHandler。所以,ThreadGroup中也有uncaughtException方法,

所以,也可以使用这个 ThreadGroup作为处理器。

如果调用了ThreadGroup中的uncaughtException,那么会发生什么?

首先,会查看这个ThreadGroup有没有父线程组,如果有,则调用父线程组的uncaguhtException方法

否则,则使用全局的线程默认未捕获的异常处理器。

如果全局的线程默认为捕获异常处理器没有定义。再看该线程没有捕获的异常是不是ThreadDeath的一个实例,

       如果是,则设么都不做。

如果不是ThreadDeath,错误信息会被输出到System.err上。

 

那么,如何设置线程的全局默认为捕获异常处理器呢?

 

调用Thread的一个静态方法:

Thread.sedDeafaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)

 

至此,线程对为捕获异常的处理的过程就是这样:

 

  1. 找出线程自己的处理器
  2. 如果找不到线程自己的处理器,则把线程所在的线程组当作处理器,主要是找到线程组中的uncaughtException方法。
  3. 如果找不到此方法,则找到此线程组所属的父线程组的这个方法。
  4. 如果还是找不到,就找线程全局默认的未捕获的异常处理器。
  5. 如果再不行,就看看这个线程没有捕获的异常是不是ThreadDeath,如果是,就什么都不做, 如果不是,就在System.err中输出错误信息

你可能感兴趣的:(java基础知识)