java实现多线程的常用方式
继承Thread类
继承Thread类,重写run方法
package com.example.course.config;
public class TestAsync extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("hello world Thread: " + i);
}
}
public static void main(String[] args) {
TestAsync testAsync = new TestAsync();
testAsync.start();
}
}
运行结果
实现Runnable接口
实现runnable接口,并且重写run方法
package com.example.course.config;
public class TestAsync implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("hello world Runnable: " + i);
}
}
public static void main(String[] args) {
TestAsync testAsync = new TestAsync();
Thread thread = new Thread(testAsync);
thread.start();
}
}
运行结果
实现Callable接口
实现Callable接口,重写call方法,这种实现方式与前两个不一样,这种有返回值
package com.example.course.config;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class TestAsync implements Callable {
static Integer a = 0;
@Override
public Integer call() throws Exception {
for (int i = 0; i < 10; i++) {
a += i;
}
return a;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestAsync testAsync = new TestAsync();
//使用FutureTask的尖括号里面的类型就是线程返回的数据类型
FutureTask<Integer> task = new FutureTask<Integer>(testAsync);
Thread thread = new Thread(task);
thread.start();
//任务是否执行完成
System.out.println(task.isDone());
//get方法会等待线程体执行完成再将结果返回
Integer result = task.get();
System.out.println(result);
}
}
注意: task.get()会阻塞,如果在调用这个方法的时候任务还没有执行完成,则会一直阻塞到方法执行完成之后再返回结果(可以再call方法内添加sleep方法验证,程序执行到get方法时会等待一段时间才打印出结果);
运行结果
使用线程池创建线程
1、如果任务不需要返回值,则调用ExecutorService的execute方法
package com.example.course.config;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestAsync {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(() -> {
System.out.println("hello world Executors: " + index);
});
}
//关闭资源
executorService.shutdown();
}
}
运行结果
2、如果任务需要返回值,则调用ExecutorService的submit方法
package com.example.course.config;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TestAsync {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
Future<String> future = executorService.submit(() -> {
System.out.println("hello world Executors: " + index);
return "submit: " + index;
});
String result = future.get();
System.out.println(result);
}
//关闭资源
executorService.shutdown();
}
}
运行结果
注意:Excutors可以创建多种线程池:
1、newSingleThreadExecutor:创建一个单线程的线程池;
2、newCachedThreadPool:创建一个可缓存的线程池;
3、newFixedThreadPool:创建一个固定长度的线程池;
4、newScheduledThreadPool:创建一个固定长度的线程池,并且支持定时任务;