1.JDK5.0之前的创建方式
方式一:继承于Thread类
1.创建一个继承于Thread类的子类
2.重写Thread类的run() --> 此线程执行的作声明在run()中
3.创建Thread类的子类的对象
4.通过此对象调用start()
方式二:实现Runnable接口
1.创建一个实现了Runnable接口的类
2.实现类去实现Runnable 中的抽象方法: run()
3.创建实现类的对象
4.将此对象作为参教传递到Thread类的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start()
比较创建线程的两种方式。
开发中优先选择:实现Runnable接口的方式
原因:
1.实现的方式没有类的单继承性的局限性
2.实现的方式更适合来处理多个线程有共享数据的情况
联系: public class Thread implements Runnable,Thread也实现了runnable的接口
相同点: 两种方式都需要重写run(),线程要执行的逻辑声明在run()中
创建线程的两个问题:
Thread类的方法:
线程的优先级:
进程可以细化为多个线程。
每个线程,拥有自己独立的: 栈、程序计数器。
多个线程,共享同一个进程中的结构:方法区、堆。
并行与并发
并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事
并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事
线程的生命周期:
内存结构:
2.JDK5.0新增的创建方式
方式三:实现Callable接口
1.创建一个实现Callable的实现类
2.实现call方法,将此线程需要执行的操作声明在call()中
3.创建Callable实现类的对象
4.将此Callable接口实现类的对象传递到FutureTask构造器中,创建FutureTask的对象
5.将FutureTask的对象作为参数传递Thread类的构造器中,创建Thread类的对象,并调用start()
6.获取Callable中call()的返回值(如果需要的话)
如何理解实现CalLable接口的方式创建多线程比实现Runnable接口创建多线程方式强大?
1. call() 可以有返回值的。
2. call() 可以抛出异常,被外面的操作捕获,获取异常的信息
3.Callable是支持泛型的
实现方式:
方式四:使用线程池
实现方式: