线程的创建与启动
继承Thread类创建线程类
- 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务
- 创建Thread类子类的实例,及创建了线程对象
- 调用线程对象的start()方法来启动该线程
实现Runnable接口创建线程类
- 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体就代表了线程需要完成的任务
- 创建Runnable实现类的实例,并以此实例作为Thread的target(形参)来创建Thread对象,该Thread对象才是真正的线程对象
用到了设计模式——静态代理
使用Callable和Future创建线程
- 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,在创建Callable实现类的实例
- 借助执行调度服务ExecutorService,获取Future对象
ExecutorService ser=Executors.new FixedThreadpool(线程数量);
Future<> result=ser.submit(实现类对象);//使用ExecutorService执行Callable类型的任务,并将结果保存在result变量中
//泛型:看cell方法中返回什么类型
- 获取值result.get();
- 停止服务ser.shutdownNow();
三个方法的区别
方法 | 区别 |
---|---|
使用Thread | 简单,但只能继承一个父类 且多个线程之间无法共享线程类的实例变量 |
使用Runnable接口 | 可实现多个接口,多个线程可以共享一个线程类的实例变量 |
使用Callable和Future | 有返回值,可抛出异常,多个线程可以共享一个线程类的实例变量 |
线程的生命周期
分为新建、就绪、运行、阻塞、死亡
新建:当程序使用new关键字创建一个线程后,该线程就处于新建状态
就绪:当程序对象调用了start()方法之后,该程序处于就绪状态
运行:处于就绪状态的线程获得了cpu,就开始执行run()方法的线程执行体
阻塞:线程调用sleep()方法主动放弃所占的处理器资源、线程调用另一个阻塞时IO方法,在该方法返回之前,该线程被阻塞、线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有、线程在等待某个通知、程序调用了线程的suspend()方法将该线程挂起
死亡:自动正常停止、外部干涉,一般不推荐使用stop()方法
其余时间在想项目怎么写