java的一大特色就是支持多线程的编程,java中给了三种实现多线程的方式。
1. 继承Thread类实现多线程
java.lang.Thread是一个线程操作的核心类,新建一个线程最简单的方法就是继承Thread类,然后覆写该类中的run()方法;
注意:在启动线程的时候是通过调用Thread类中的start()方法来调用run()方法,不能直接调用run方法,否则多线程并没有启动成功。
2. Runnable接口实现多线程
Thread类的核心功能就是进行线程的启动,用Runnable接口来实现多线程避免了单继承局限;此时我们不能直接调用Thread类中的start()方法,但Thread类提供了一个构造方法,可接受Runnable接口对象:
public Thread(Runnable target);
** 通过Thread的构造将Runnable接口对象传进去,进而调动Start()方法启动多线程。
**Runnable接口对象创建有两种方式来定义---》匿名内部类或Lambda表达式;
(1) 匿名内部类定义---》如下:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
}).start();
(2) Lambda表达式定义---》如下:
Runnable runnable=()->System.out.println("hello world");
new Thread(runnable).start();
我们经常使用这两种操作来进行Runnable对象的创建;
3. Callable接口实现多线程
Runnable中的run方法是没有返回值的,它的设计也遵循了主方法的设计原则:线程开始了就别回头。
但有时我们需要一些返回值,此时可以使用Callable接口来实现多线程。
在Thread类中提供了一个构造方法:
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
public Thread(Runnable target)
所以我们可以通过FutureTask类来启动多线程,例如:
FutureTask< String> task=new FutureTask<>(new myThread());
new Thread(task).start();
创建完线程我们就来看看线程都有哪些运行状态,线程的运行状态分为五种:创建--就绪状态--阻塞状态--运行状态--终止状态;
这五种状态相互之间又是怎样相互转换的呢?如下图所见: