目录
Java 中创建线程有四种方式,分别是:
继承 Thread 类
-
首先定义一个类来继承 Thread 类,重写 run 方法。
-
然后创建这个子类对象,并调用 start 方法启动线程。
示例:
public class ThreadDemo1 extends Thread {
@Override
public void run() {
while (true) {
System.out.println("thread demo1 is running");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
测试代码:
public class MainThreadDemo {
public static void main(String[] args) {
new ThreadDemo1().start();
}
}
实现 Runnable 接口
-
首先定义一个类实现 Runnable 接口,并实现 run 方法。
-
然后创建 Runnable 实现类对象,并把它作为 target 传入 Thread 的构造函数中
-
最后调用 start 方法启动线程。
示例:
public class ThreadDemo2 implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("thread demo2 is running");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
测试代码:
public class MainThreadDemo {
public static void main(String[] args) {
new Thread(new ThreadDemo2()).start();
}
}
实现 Callable 接口,并结合 Future 实现
-
首先定义一个 Callable 的实现类,并实现 call 方法。call 方法是带返回值的。
-
然后通过 FutureTask 的构造方法,把这个 Callable 实现类传进去。
-
把 FutureTask 作为 Thread 类的 target ,创建 Thread 线程对象。
-
通过 FutureTask 的 get 方法获取线程的执行结果。
import java.util.concurrent.Callable;
public class ThreadDemo3 implements Callable<String> {
@Override
public String call() {
for (int i = 0; i < 10; i++) {
System.out.println("thread demo3 is running");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return "success";
}
}
测试代码:
public class MainThreadDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> task = new FutureTask<>(new ThreadDemo3());
new Thread(task).start();
String result = task.get();
System.out.println(result);
}
}
通过线程池创建线程
方式一:Runnable
-
首先,定一个 Runnable 的实现类,重写 run 方法。
-
然后创建一个拥有固定线程数的线程池。
-
最后通过 ExecutorService 对象的 execute 方法传入线程对象。
示例:
public class ThreadDemo4 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("[" + Thread.currentThread().getName() + "]:thread demo3 is running, " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
通过线程池创建线程:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class MainThreadDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
ExecutorService executorService = new ThreadPoolExecutor(
8, 16, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()
);
for (int i = 0; i < 3; i++) {
executorService.execute(new ThreadDemo4());
}
executorService.shutdown();
}
}
这种方法有一个缺点,无法对执行线程的任务传参,也没办法获取线程执行后的返回值,因此,实际使用的时候,更多的场景是使用 CompletableFuture 类去创建线程任务。
方式二:CompletableFuture
-
使用 CompletableFuture 类去创建线程任务。
-
然后创建一个拥有固定线程数的线程池。
-
最后通过 CompletableFuture.supplyAsync 方法创建线程任务。
定义一个 Task 类:
public class ThreadDemo4 {
public String count(int start, int end) {
for (int i = start; i < end; i++) {
System.out.println("[" + Thread.currentThread().getName() + "]: thread demo3 is running, " + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return "success";
}
}
创建线程池:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class MainThreadDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
ExecutorService executorService = new ThreadPoolExecutor(
8, 16, 60, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy()
);
List<CompletableFuture<String>> futureList = new ArrayList<>();
List<String> results = new ArrayList<>();
for (int i = 0; i < 3; i++) {
int finalI = i;
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> new ThreadDemo4().count(finalI, finalI + 10), executorService)
.whenComplete((result, exception) -> {
results.add(result);
});
futureList.add(future);
}
CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])).get(10, TimeUnit.MINUTES);
executorService.shutdown();
System.out.println(results);
}
}
CompletableFuture 创建线程的时候,也是调用的ExecutorService.execute 方法创建线程任务,但是,CompletableFuture 会将线程封装为 AsyncSupply 对象,在执行结束后,保存线程的计算结果。
参考:
标签:Java,Thread,创建,util,线程,import,new,public From: https://www.cnblogs.com/larry1024/p/17789035.html