线程生命周期
1、线程从创建到结束就是一个生命周期,在一个周期中有各种状态,可以互相转换。
2、新建态(NEW):刚创建好的状态
就绪态(RUNNABLE):线程准备好了运行资源,等待CPU
运行态(RUNNABLE):CPU正在执行
阻塞态:线程主动休息,或者缺少运行资源,即使有CPU也无法运行
TIMED_WAITING:阻塞态,调用了有时间限制的wait方法、sleep方法
BLOCKED:阻塞态(等待锁、I\O)
WAITING:阻塞态,调用了wait方法,等待唤醒
死亡态(TERMINATED):线程运行完成或出现异常,线程结束
3、状态转换图
4、获取线程状态的方法
getState(): 返回当前对象的状态对象,返回值类型为Thread.State,是Thread的内部类
线程池
1、当没有线程池时,每次使用都会先创建线程对象,启动线程,当线程正常结束时,线程对象就会消失,被垃圾回收机制回收,线程的创建和消失浪费了大量的时间;如果任务本身破坏力比较大,可能会把线程对象结束掉,就无法继续完成任务。
2、当有线程池时,没有任务的时候,先把线程对象准备好,存储到一个容器中,当有任务时就可以直接使用,如果任务可以顺利完成,这个线程对象不会进入死亡状态,而是被回收,继续活跃。如果任务破坏力较大,任务会把线程搞死,线程池会继续提供下一个线程,继续完成这个任务。 破坏力较大指耗时大。
3、使用方法:
获取线程池对象,创建任务对象,将任务对象交给线程池中
4、获取线程池对象的方法
工具类:Executors:生成线程池的工具类,根据需求生成指定大小的线程池
ExecutorService Executors.newSingleThreadPool():创建一个有单个线程的线程池
ExecutorService Executors.newFixedThreadPool(int nThreads):创建一个指定线程数量的
5、创建任务类对象:Runnable的实现类对象,用于定义任务内容
6、将任务类对象提交到线程池中
ExecutorService:是一个接口,使用方法获取这个接口的实现类对象,调用这个接口中的方法
submit(Runnable r):可以将一个任务类对象,提交到线程池中,如果有空闲的线程,就可以马上运行这个任务,如果没有空闲线程,那么这个任务就需要等待。
shutDown():结束线程池,已经提交的全部保证完成,不准继续提交了
shutDownNow():结束线程池,已经开始运行的,保证完成;但是还没有运行的,已经提交的,不给运行了,作为返回值范围;对于没有提交的,不准提交。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String[] args) {
ExecutorService ns = Executors.newFixedThreadPool(5);
Runnable t1 = new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println(i);
}
}
};
Runnable t2 = new Runnable() {
@Override
public void run() {
for(int i=10;i<20;i++) {
System.out.println(i);
}
}
};
Runnable t3 = new Runnable() {
@Override
public void run() {
for(int i=20;i<30;i++) {
System.out.println(i);
}
}
};
Runnable t4 = new Runnable() {
@Override
public void run() {
for(int i=30;i<40;i++) {
System.out.println(i);
}
}
};
Runnable t5 = new Runnable() {
@Override
public void run() {
for(int i=40;i<50;i++) {
System.out.println(i);
}
}
};
ns.submit(t1);
ns.submit(t2);
ns.submit(t3);
ns.submit(t4);
ns.submit(t5);
ns.shutdown();
}
}
线程池