一、线程的生命周期和状态
- 新建状态:一个Thread或其子类的对象被声明并创建,但还未被执行。此时,线程对象已经被分配了内存空间和其他资源,并已被初始化,但是该线程尚未被调度。
- 就绪状态:也称为可执行状态。处于新建状态的线程被启动后,将进入线程队列排队等待CPU资源,此时已经具备了运行的条件。一旦轮到它享用CPU资源时,便可以脱离创建它的主线程独立开始自己的生命周期。另外,原来处于阻塞状态的线程被解除阻塞后也将进入就绪状态。
- 执行状态:当就绪状态的线程被调度并获得CPU的资源后,便进入执行状态。
处于执行状态的线程在下列情况下将让出CPU资源:
(1)线程执行完毕
(2)有比当前线程优先级更高的行程处于就绪状态。
(3)线程主动休眠一段时间
(4)线程在等待某一资源 - 阻塞状态:一个正在执行的线程,如果在某些特殊情况下将让出CPU资源,暂时终止自己的执行线程处于这种不可执行的状态。、
以下几种情况可使得一个线程进入阻塞状态:
(1)调用sleep()或者yield()的方法
(2)为等待一个条件变量,线程调用wait()方法
(3)该线程与另一线程join()在一起。
【当某一线程调用join()方法时,其他线程会等到该线程结束后才开始执行,但join()会抛出InterrruptedException异常】 - 消亡状态:该线程不再具有继续执行的能力。
导致线程消亡的原因有:
(1)正常运行的线程完成了他的工作。即执行完了run方法好的最后一条语句并退出
(2)当进程因故停止运行时,该进程中的所有线程将被强行终止
二、利用Thread类的子类创建线程
在Thread类的一个子类中激活线程需:
(1)此类必须是继承自Thread类;
(2)线程所要执行的代码中必须写在run()方法中。
练习代码如下:
class MyThread extends Thread{
private String who;
public MyThread(String str) //构造方法
{
who = str; //设置成员变量who
}
/*
* 线程所要执行的代码必须写在run()方法内,但是在主函数中调用时调用的是start()方法。
* start()方法使该线程由新建状态变为就绪状态。
*/
public void run() //覆盖父类的run()方法,编写要执行的内容
{
for(int i = 0;i < 5;i++)
{
try {
sleep((int)(1000*Math.random())); //sleep()是模拟网络延时,但会抛出异常;
}
catch (InterruptedException e) { }
System.out.println(who + "芜湖起飞!!!今年冲冲冲!!!");
}
}
}
public class ThreadSon
{
public static void main(String[] args) {
MyThread you = new MyThread("小猪猪");
MyThread me = new MyThread("小可爱");
Thread t1 = new Thread(you);
Thread t2 = new Thread(me);
t1.start(); //调用的start()方法而不是run()方法;
t2.start();
System.out.println("等待起飞!!");
}
}
三、利用Runnable接口创建线程(常用)
使用 Runnable接口的好处:(1)可以间接处理Thread类的子类创建线程无法多重继承的问题;(2)适合于多个线程处理同一资源。
练习代码如下:
class MyThread1 implements Runnable //利用Runnable接口实现MyThread1类
{
private String who;
public MyThread1(String str) //构造方法
{
who = str; //设置成员变量who
}
@Override
public void run() {
for(int i = 0;i < 5;i++)
{
try {
//sleep()会抛出异常,其次注意使用的接口,所以sleep前要加Thread;
Thread.sleep((int)(1000*Math.random()));
}
catch (InterruptedException e)
{
System.out.println(e.toString());
}
System.out.println(who + "芜湖起飞!!!今年冲冲冲!!!");
}
}
}
public class Running {
public static void main(String[] args) {
MyThread1 you = new MyThread1("小猪猪");
MyThread1 me = new MyThread1("小可爱");
Thread t1 = new Thread(you);
Thread t2 = new Thread(me);
t1.start(); //激活线程
t2.start();
System.out.println("等待起飞!!");
}
}