1-线程的实现与状态

来源:互联网 发布:安泰管理学院知乎 编辑:程序博客网 时间:2024/06/05 03:06

进程与线程

进程程序的一次执行过程,从代码加载、执行到执行完毕的一个完整过程,这个过程也是进程本身从产生、发展到最后消亡的过程。 一个进程就代表一个程序,操作系统能运行多个同时进程。多进程是实现并发的一种有效手段。

线程:线程和进程一样,都是实现并发的一个基本单位。线程是在进程的基础上进行的进一步的划分。多线程是说一个进程在执行过程中可以产生多个线程,这些线程可以同时存在、同在运行

Java中线程的实现

第一种:继承Thread类,重写run()方法

此方法为线程的主体, 开启线程需要调用start()方法,而不能直接调用run()方法,若直接调用run()方法不会开启线程,仍然是在单线程里执行。

一般在重复调用start()方法时会抛出“IllegalThreadStateException”异常

为什么启动线程不能直接使用run()方法呢? 因为线程的运行需要本机操作系统的支持。下面为start()方法在Thread类中的定义:

public synchronized void start(){          if(threadStatus != 0)              throw new IllegalThreadStateException();          ...          start0();          ...      }      private native void start0();

实际上此处真正调用的是start0()方法,此方法在声明处使用的native关键字声明,此关键字表示调用本机的操作系统函数,因为多线程的实现依靠底层操作系统的支持。


第二种:实现Runnable接口

Runnable接口中只定义了run()一个抽象方法。


Thread和Runnable的联系和区别

联系:Thread类实现了Runnable接口,下面是Thread类的定义

所以如果在继承Thread类时没有重写run()方法,则target = null,不会执行任何操作。

两种实现方式的区别:
继承Thread类不适合多个线程共享资源,因为每创建一个线程对象,每个对象都有自己的属性、方法,也都有自己的run()方法;继承Thread类后就不能再继承其他的类

实现Runnable接口,方便实现资源共享,可以使用一个实现Runnable接口的类对象创建多个线程,它们共用一个Runnable对象,共用里面的属性、方法,共用run()方法。实现Runnable接口不影响继承其他类和实现其他接口,灵活性更好

 

线程的五种状态

新建状态:当一个线程对象被创建后就处于新建状态,这时还只是一个普通的对象,不能被线程调度程序调度


准备状态调用了start()方法后就进入准备状态,进入线程队列排队,随时可能被线程调度程序调度,获取CPU执行时间。一旦进入准备状态的线程就不能再回到新建状态


运行状态获取了CPU时间就进入运行状态,但是持续执行的时间是不能保证的,处于运行状态的线程随时可能被调度回到准备状态。由于需要等待某些必要的条件,或执行了特定的方法,也可能进入阻塞状态。


等待/阻塞状态:由于等待、阻塞、或睡眠等原因

睡眠:调用了sleep()方法
阻塞:调用了阻塞方法,而正好又满足了阻塞的情况,则进入阻塞状态,直到阻塞条件解除再进入准备状态。比如,调用了接受网络连接请求的accpet()方法,而此时没有连接请求的到来;执行一些耗时的输入输出操作
等待:运行的线程由于逻辑条件不满足,自己调用wait()方法进入等待状态,直到收到通知的消息才进入准备状态


死亡状态:线程正确执行完毕或发生异常而终止执行时,就进入死亡状态。死亡状态的线程可以当作普通对象来使用,例如调用其成员方法或属性,但不能再次启动执行,否则会抛出IllegalThreadStateException异常 。

 

0 0