多线程实现方式

创建线程的几种方法

继承Thread

  继承Thread类并重写run()方法,

1
2
3
4
5
6
7
8
9
public class TestThread extends Thread {
@Override
public void run() {
super.run();
for (int i = 0; i < 20; i++) {
System.out.println(i);
}
}
}

  创建TestThread对象,并调用start()方法

1
2
3
4
public static void main(String[] args) {
TestThread testThread = new TestThread();
testThread.start();
}

  如果逻辑并不复杂,可以直接创建Thread对象并重写run()方法

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
super.run();
for (int i = 0; i < 20; i++) {
System.out.println(i);
}
}
}.start();
}

实现Runnable

  实现Runnable接口并重写run()方法

1
2
3
4
5
6
7
8
public class TestRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(i);
}
}
}

  创建TestRunnable对象,创建Thread对象,并传入TestRunnable对象

1
2
3
4
public static void main(String[] args) {
TestRunnable testRunnable = new TestRunnable();
new Thread(testRunnable).start();
}

  或者直接传入匿名类

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(i);
}
}
}).start();
}

  注意:如果在创建Thread对象时,传入Runnable同时重写run()方法,那么它们两个都会被执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("执行Runnable匿名类的run方法");
}
}) {
@Override
public void run() {
super.run();
System.out.println("执行重写run方法");
}
}.start();
}

实现Callable

  实现Callable类,重写run()方法并指定其泛型类型

1
2
3
4
5
6
public class TestCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "测试";
}
}

  创建FutureTask对象,并传入TestCallable,将FutureTask放在Thread中执行,执行后通过FutureTaskget()方法可以获取到TestCallable的返回值

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
TestCallable testCallable = new TestCallable();
FutureTask<String> futureTask = new FutureTask<>(testCallable);
new Thread(futureTask).start();
try {
String s = futureTask.get();
System.out.println(s);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}