线程的创建和启动
1:继承Thread类创建线程类
步骤:
(1)线程类继承Thread类,并对Thread类中的run()方法进行重写
(2)创建线程类对象。
(3)调用线程对象的start()方法来启动该线程。
注意:run()方法是线程执行体,但并不是所有线程的执行体都是run()方法。主线程的线程执行体就是main()方法。使用继承Thread类方式创建的线程类,多个线程之间无法共享线程类的实例变量。
2:实现Runnable接口创建线程类
步骤:
(1)实现Runnable接口,并对run()方法进行重写。
(2)创建实现Runnable接口的类实例,用此实例为target,作为Thread类的构造函数的参数,创建线程对象。
(3)调用Start()方法启动该线程。
提示:Runnable对象仅仅是Thread对象的target,并不是线程对象,实际的线程对象依然是Thread实例,只不过该实例走的run()方法执行体是target的run()方法。
3:使用Callable 和 Future创建线程
步骤:
(1)实现Callable接口,并对call()方法进行重写。
(2)创建实现了Callable接口的类实例,注意,此实例并不能直接作为target传给Thread构造器。创建FutureTask类的对象,该对象封装该callable对象。
(3)FutureTask类的对象作为target传给Thread构造器。
(4)调用strat()方法启动该线程。
注意:Callable接口的call()方法是有返回值的。还可以抛出异常。获取线程执行call()方法的执行体之后返回值是用FutureTask类对象的get()方法。
4:创建线程的三种方式对比
对于实现Runnable接口和实现Callable接口来创建线程都可以实现多线程,不过实现这两种接口创建线程的方式不一样,run()方法不允许有返回值,并且不允许抛出异常;而call()方法允许抛出异常,并且有返回值。这里把实现这两个接口创建线程的方式归并为一种。
采用实现接口创建线程的方式优点:
(1)还可以继承其他类。
(2)多个线程可以共享一个target对象。
采用实现接口创建线程的方式缺点:
(1)编程稍微复杂。
(2)获取当前线程必须使用Thread.currentThread()。
采用继承Thread创建线程的方式优点:
(1)编程稍微简单
(2)获取当前线程可以直接使用this。
采用继承Thread创建线程的方式缺点:
(1)继承了Thread,就不能继承其它类了。
(2)多个线程不能贡献同一份实例变量。
总结来说,一般都是使用实现接口的方式来创建线程,这样子的话,多线程能够共享同一个target的实例变量;也更加灵活。符合面向接口编程原则。