线程启动的几种方法
继承Thread类
继承Thread类,覆盖Thread类的run方法,在方法中实现自己的业务逻辑。例如:
class MyThread extends Thread {
@Override
public void run() {
System.out.println(“use extends method start thread.”);
}
}
实现Runnable接口的方式
直接使用匿名类,或者lamda语法,创建线程,例如:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“use interface start a thread”);
}
});
thread.start();
使用java8的语法更简单:
Thread thread1 = new Thread(()->doSomething());
thread1.start();
private static void doSomething() {//处理的业务逻辑
}
上面的两种方法本质上是一样,都是覆盖Runnable接口的run方法,因为Thread内部调用的都是run方法。上面的方法单纯的处理业务逻辑,没有返回值,有时并不能适用于需要返回值的场景。
实现Callable接口,提交给线程池的方式
创建一个类,这个类实现了Callable接口,然后创建一个线程池,将这个类的实例提交(submit)给线程池,然后返回future,调用future的get方法获取返回值,get是阻塞方法。Callable参数是泛型,可以根据实际情况写类名,用例中写的事String,例如下面的代码:
class ThreadWithReturn implements Callable {
@Override
public String call() throws Exception {
return “with return thread”;
}
}
…
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future result = executorService.submit(new ThreadWithReturn());
try {
System.out.println(result.get());
executorService.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
这种方式需要创建线程池,同时还要关闭线程池,否则线程会挂在这里,并不友好。有更友好的FutureTask类。
FutureTask完成返回值线程
简述:FutureTask实现了Future接口和Runnable接口,所以它可以有Runable用法(提交给Thread),也可以给Excutor执行,也可以直接调用线程执行(Future.run()),用例代码如下:
FutureTask task = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
return “hello world”;
}
});
// task.run();直接调用run也可以创建子线程
Thread helper = new Thread(task);//提交给Thread执行
helper.start();
try {
String fu = (String) task.get();
System.out.println(fu);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
上面的FutureTask用法是牛刀小试的用法,更丰富的功能,见下一篇博客。
本次代码:
package com.example.demo;
import java.util.concurrent.*;
class MyThread extends Thread {
@Override
public void run() {
System.out.println("use extends method start thread.");
}
}
class ThreadWithReturn implements Callable<String> {
@Override
public String call() throws Exception {`在这里插入代码片`
return "with return thread";
}
}
public class ThreadTest {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("use interface start a thread");
}
});
thread.start();
Thread thread1 = new Thread(() -> doSomething());
thread1.start();
Thread extendThread = new MyThread();
extendThread.start();
ExecutorService executorService = Executors.newFixedThreadPool(1);
Future<String> result = executorService.submit(new ThreadWithReturn());
try {
System.out.println(result.get());
executorService.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
FutureTask task = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
return "hello world";
}
});
// task.run();
Thread helper = new Thread(task);
helper.start();
try {
String fu = (String) task.get();
System.out.println(fu);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private static void doSomething() {
// TODO what you want to do
}
}