线程的创建和启用
一、通过继承Thread类来创建线程
1、继承Thread,重写run方法,run方法的方法体就代表了县城需要执行的任务
2、创建Thread子类实例,即创建了线程对象
3、调用线程对象.start()方法,启动该线程
//通过继承Thread类来创建线程
publicclass FirstThread extends Thread
{
private int i;
//重写run方法,run方法的方法体就是线程的执行体
public void run
{
for(i;i<100;i++)
{
//继承Thread后,可通过getName()直接返回当前线程名;this用于获取当前线程
System.out.println(getName()+""+i);
}
}
}
publicstatic void main(String[] args)
{
for(int i;i<100,i++)
{
//调用Thread的currentThread,currentThread用来获取当前正在执行的线程
System.out.println(Thread.currentThread().getName()+""+i);
if(i==20 ) //当i=20时,以下两条线程被创建、启动
{
//创建并启动第一条线程
new FirstThread().start();
//创建并启动第二条线程
new FirstThread().start();
}
}
}
二、通过实现Runnable接口创建线程
1、实现Runnable接口,实现run方法
2、通过newThread(st,"新线程1").start();创建并启动线程
//通过实现Runnable接口创建线程
publicclass SecondThread implements Runnable
{
private int i;
//重写run方法,run方法的方法体就是线程的执行体
public void run
{
for(i;i<100;i++)
{
//继承Thread后,只能通过currentThread获得当前线程
System.out.println(Thread.currentThread().getName()+""+i)
}
}
}
publicstatic void main(String[] args)
{
for(int i;i<100,i++)
{
System.out.println(Thread.currentThread().getName()+""+i);
if(i==20)
{
//通过newThread(target,name)来创建并启动第一条线程
new Thread(st,"新线程1").start();
//通过newThread(target,name)来 创建并启动第二条线程
new Thread(st,"新线程2").start();
}
if(i>20 &&!st.isAlive())//isAlive判断线程状态,死亡态返回false
{
//试图再次启动该线程
st.start();
}
}
}
通过实现Runnable接口创建的线程SecondThread并非真正的线程对象,只能作为线程对象的target目标,实际上的线程是target类,创建的多条线程共享线程类target实例的属性方法;
而使用第一种方法继承Thread类所创建的线程就是线程对象本身。所以用this可以直接表示当前线程对象。
三、两种创建线程方式对比
创建方式 | 优点 | 缺点 |
实现Runnable接口(常用) | 1、 还可继承其他类 2、 多线程共享一个target对象,所以非常适合多个相同线程处理同一份资源 | 编程相对复杂,必须使用Thread.currentThread()获取当前线程 |
实现Thread类 | 编写简单,直接this便可获得当前线程 | 已经继承Thread,故无法继承其它父类 |
线程生命周期
New
——》新建状态,java虚拟机分配内存,初始化成员变量——》
Start
——》就绪状态,虚拟机为齐创建方法调用栈,准备就绪,等待运行——》虚拟机通过线程调度,确定执行哪个就绪态线程——》
Run
——》获得CPU,开始执行run方法的方法体——》运行状态——》
Blocked
——》当一条线称运行时,它不可能一致霸占CPU,在运行过程中需要被中断,使其它线程也有机会运行——》被中断的线程进入阻塞状态——》
Dead
——》run()方法体执行完毕,线程结束——》死亡状态
注意:
-
一个线程只能调用一次start()方法,启用一次,死亡后也无法再次运行,故一条线程在其生命周期里只有一次调用start的机会。
-
启用线程调用start ,而非run,直接调用线程类的run方法,该方法立刻执行,在返回之前,其它线程无法并行执行。类似于执行一个类的普通方法,而非执行线程执行体,所以起不到多线程高校并发执行的效果。
-
死亡可为run方法执行完毕,或者线程直接抛异常,还可直接调用该线程的stop()方法结束该线程;但最后一种方式容易导致死锁,通常不推荐使用。