线程的状态和生命周期
概述:
-
含义:
- 线程是程序中的一个独立的执行路径,是一个动态的概念,一定是正在运行中的进程中的一部分。因此从创建到消亡的各个过程,有个个状态,状态之间还可以相互转换
-
状态罗列:
- 新建态:刚刚创建好的线程对象,刚new出来
- 就绪态:所有的资源都分配好了,就差cpu来运行的状态
- 运行态:CPU正在运行的状态
- 阻塞态:线程无法运行的状态,缺少资源,线程主动休息。即使CPU来了,也无法运行的状态
- 死亡态:线程正常结束,或者主动关闭
java中关于线程状态的方法和描述
-
描述:
- 上述线程状态,只是理论上的状态,java中有的状态获取不到。
- 在java中,无法获得就绪态;也可以获得不同原因的阻塞态
-
方法:
- Thread.State getState()
- 返回该线程的状态。
- 返回值:是一个线程状态对象,对象属于State类,是Thread中的内部类
- 是一个枚举类型
- 枚举:罗列、穷举
- 某个类型,对象是有限的,那么外界就不应该随意创建对象。就在定义类的时候,就将那些对象全部在类中创建好了,只给外界访问方式。这种类型就是枚举
- 概念:在枚举类形,定义好的那些对象就叫枚举项,都是一些静态的一些常量,可以通过类名.枚举项名称来访问
- 线程状态:线程状态就是一个类,但是线程状态是有限个的,因此将线程状态定义为枚举类型Thread.State,里面有提前准备好的该类对象6个,表示6种线程状态,将来可以直接获取使用,我们不能自己创建线程状态
- Thread.State getState()
//创建一个线程
Thread th = new Thread() {
@Override
public void run() {
// TODO Auto-generated method stub
}
};
//打印为new
System.out.println(th.getState());
th.start();
//打印RUABLE,处于运行态
System.out.println(th.getState());
Thread.sleep(10);//主线程睡眠,让th有住够的时间运行完
//打印TERMINATED,表示线程结束
System.out.println(th.getState());
}
线程池
线程池的理解
- 如果没有线程池,当系统中出现大量小的线程时,将会将时间大量浪费在创建和销毁上,
- 有线程池的话,池中有很多的可以随时执行任务的线程,当有任务时,可选一天来执行,任务结束后,只需将该线程回收到线程池中,不用销毁。节约大量时间。
- 好处:
- 效率高:当大量小任务时,不会将时间浪费在线程的创建和销毁
- 安全性高:如果某些任务把线程搞挂,可以立即使用线程池中其他的代替
线程池的使用
-
获取线程池:
- Executors工具类中重点ExecutorService类型就是一个线程池
- static ExecutorService newFixedThreadPool(int nThreads)
- 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
- static ExecutorService newSingleThreadExecutor()
- 创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
-
使用线程池:
- ExecutorService是一个接口,Executor的方法返回的是该接口的实现类的对象,都拥有该接口的实现方法
- 常用方法:
-
Future<?> submit(Runnable task)
- 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
-
线程池要调用专用方法关闭线程池,结束程序
-
void shutdown()
- 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
-
List shutdownNow()
- 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
-
//获取线程池对象
ExecutorService es = Executors.newFixedThreadPool(2);
//提交给线程池任务
es.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i < 200;i++) {
System.out.println(i + "...." + Thread.currentThread().getName());
}
}
});
es.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i < 200;i++) {
System.out.println(i + "...." + Thread.currentThread().getName());
}
}
});
es.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i < 200;i++) {
System.out.println(i + "...." + Thread.currentThread().getName());
}
}
});
//关闭线程池
//es.shutdown();
List<Runnable> list = es.shutdownNow();
System.out.println(list + "########################################################");