创建线程的方法
- 继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("MyThread");
}
public static void main(String[] args) {
new MyThread().start();
}
}
- 实现Runable接口
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("MyThread");
}
public static void main(String[] args) {
new Thread(new MyThread()).start();
}
}
继承Thread和实现Runable哪种方式比较好?实现Runable的方式比较灵活,因为java是单继承,实现Runable接口以后,该线程类还能从其他的类继承。
- 实现Callable接口
public class MyThread implements Callable<String> {
@Override
public String call() {
return "success";
}
public static void main(String[] args) throws Exception {
//通过线程池启动
ExecutorService executorService = Executors.newCachedThreadPool();
Future<String> future = executorService.submit(new MyThread());
//阻塞等待线程执行完
String result = future.get();
System.out.println(result);
//通过FutureTask来启动
FutureTask<String> task = new FutureTask<>(new MyThread());
new Thread(task).start();
result = task.get();
System.out.println(result);
}
}
Future用来接收线程未来可能返回值的类, Future#get() 是个阻塞方法。FutureTask可以通过new Thread运行,也能接收Callable的返回值,它的本质是继承了Runnable接口和Futrere接口
- 通过lamda表达式创建
public static void main(String[] args) throws Exception {
new Thread(()->{
System.out.println("MyThread");
}).start();
}
- 使用线程池创建
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newCachedThreadPool();
service.execute(()->{
System.out.println("hello ExecutorService");
});
}
这五种创建线程的方式本质都是使用的new Thread()对象,然后执行start()