Java创建线程的几种方式:
Java使用Thread类代表线程,所有线程对象都必须是Thread类或者其子类的实例。Java可以用以下5种方式来创建线程:
- 继承Thread类创建线程;
- 实现Runnable接口创建线程;
- 实现Callable接口,通过FutureTask包装器来创建Thread线程;
- 使用ExecutorService、Callable(或者Runnable)、Future实现由返回结果的线程。
- 使用CompletableFuture类创建异步线程,且是据有返回结果的线程。
继承Thread类创建线程
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extends Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
//继承Thread类
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行了");
}
}
实现Runnable接口创建线程
如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口
//创建类实现Runnable接口
class MyRunable implements Runnable{
@Override
public void run() {
System.out.println("子线程执行了……");
}
public static void main(String[] args) {
//main方法中执行
MyRunable mr1 = new MyRunable();
Thread t1 = new Thread(mr1);
t1.start();
}
}
实现Callable接口
实现一个Callable接口(它是一个具有返回值的)
需要借助FutureTask类,比如获取返回结果
class MyCallable implements Callable<Integer>{
//线程启动后会执行的方法
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i = 1 ; i <= 1000;i++){
sum +=i;
}
return sum;
}
public static void main(String[] args) {
//main方法中执行
Callable<Integer> callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
//获取一个线程,FutureTask本质上是Runable接口的实现
Thread t1 = new Thread(futureTask);
System.out.println("main方法start……");
t1.start();//本质还是执行了Runable中的run方法,只是run方法调用了call方法
//获取返回的结果
System.out.println(futureTask.get());//获取开启的线程执行完成后返回的结果
}
}
使用线程池
使用ExecutorService、Callable(或者Runnable)、Future实现由返回结果的线程
Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口:
public class ThreadPoolTest1 {
public static void main(String[] args) {
Runnable mr = new MyRunnable();
//创建一个可缓存的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(mr);
executorService.execute(mr);
executorService.execute(mr);
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行了" );
}
}
使用CompletableFuture类创建异步线程
Callable + Thread的方式有一定的局限性。
Callable+Thread的方法提供多线程和返回值的能力但是在获取返回值的时候会阻塞主线程。
Callable<Integer> callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
Thread t1 = new Thread(futureTask);
t1.start();//本质还是执行了Runable中的run方法,只是run方法调用了call方法
//获取返回的结果,这里会阻塞主线程
System.out.println(futureTask.get());//获取开启的线程执行完成后返回的结果
这种方式具体的我就不是很熟了,用得少~