Java创建线程的几种姿势

Java创建线程的几种姿势

一、简单介绍

在并发编程中,最基本的就是创建线程了。一般创建线程有四种方式:

  1. 继承Thread
  2. 实现Runnable接口
  3. 实现Callable接口,结合FutureTask使用
  4. 利用线程池ExecutorService、Callable、Future来实现

二、基本使用

1.继承Thread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ExtendThread extends Thread{
String threadName;
public ExtendThread(String name) {
super(name);
threadName = name;
}
@Override
public void run() {
System.out.println("Thread -- Run--"+threadName);
}
public static void main(String args[]){
ExtendThread extendThread1 = new ExtendThread("Thread1");
ExtendThread extendThread2 = new ExtendThread("Thread2");
extendThread1.start();
extendThread2.start();
}
}

继承Thread类,覆写run()方法,通过start()方法启动新线程。

2.实现Runnable接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ImplRunnable implements Runnable {
@Override
public void run() {
System.out.println("Thread--Run"+Thread.currentThread().getName());
}
public static void main(String args[]){
ImplRunnable implRunnable = new ImplRunnable();
Thread thread1 = new Thread(implRunnable,"Thread1");
Thread thread2 = new Thread(implRunnable,"Thread2");
thread1.start();
thread2.start();
}
}

实现Runnable接口,实现run()方法,获取实现Runnable接口的实例,创建Thread,通过start()启动新的线程

3.实现Callable接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ImplCallable implements Callable {
@Override
public String call() throws Exception {
System.out.print("Hello");
return "World";
}
public static void main(String args[]) {
ImplCallable implCallable = new ImplCallable();
FutureTask<String> futureTask = new FutureTask<String>(implCallable);
new Thread(futureTask).start();
try {
System.out.println(futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}

实现Callable接口,实现call()方法,创建FutureTask实例,将FutureTask作为Thread的参数创建Thread,通过start()启动一个新的线程,通过FutureTask.get()获取线程的返回结果。

4.通过线程池创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ThreadPoolDemo {
public static void main(String args[]) {
System.out.println("Threadname:"+Thread.currentThread().getName());
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("Hello" + Thread.currentThread().getName());
}
});
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("World" + Thread.currentThread().getName());
}
});
}
}

创建线程池,创建Runnable任务,通过execute执行任务

三、使用区别

Runnable和Callable区别

Runnable与Callable最根本的区别就是:

  • Runnable无返回结果
  • Callable有返回结果
1.Runnable

Runnable不关心返回,所以任务自己默默的执行就可以了,也不用告诉我完成没有,我不care,您自己随便玩,所以一般使用就是

1
new Thread(new Runnable() { public void run() {...} }).start()

换成JDK8的 lambda表达式就更简单了

1
new Thread(() -> {}).start();
2.Callable

Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞!

1
2
3
FutureTask<Object> future = new FutureTask<>(() -> null);
new Thread(future).start();
Object obj = future.get(); // 这里会阻塞,直到线程返回值
Neil Liu wechat
个人微信,欢迎交流
让我感受下知识的力量~