1、可以实现 Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
System.out.println(Thread.currentThread().getName() + ":" + x);
}
}
}
/*
* 方式2:实现Runnable接口
* 步骤:
* A:自定义类MyRunnable实现Runnable接口
* B:重写run()方法
* C:创建MyRunnable类的对象
* D:创建Thread类的对象,并把C步骤的对象作为构造参数传递
*/
public class MyRunnableDemo {
public static void main(String[] args) {
// 创建MyRunnable类的对象
MyRunnable my = new MyRunnable();
// 创建Thread类的对象,并把C步骤的对象作为构造参数传递
// Thread(Runnable target)
// Thread t1 = new Thread(my);
// Thread t2 = new Thread(my);
// t1.setName("林青霞");
// t2.setName("刘意");
// Thread(Runnable target, String name)
Thread t1 = new Thread(my, "林青霞");
Thread t2 = new Thread(my, "刘意");
t1.start();
t2.start();
}
}
2、继承Thread类
/**
* Create By CodeCow on 2020/8/3.
*/
public class TestThread {
public static void main(String[] args) {
MyThread mt = new MyThread("新线程————看大片");
//开启新线程
mt.start();
//在主方法中执行for循环
for (int i = 0; i < 5; i++) {
System.out.println("main线程————撸代码,没意思。。" + i);
}
}
//继承Thread类
public static class MyThread extends Thread {
//定义指定线程名称的构造方法
public MyThread(String name) {
//调用父类的String参数的构造方法,指定线程的名称(原理:利用继承特点,将线程名称传递)
super(name);
}
//重写run方法,定义线程要执行的代码
@Override
public void run() {
for (int j = 0; j < 5; j++) {
//getName()方法 来自父亲(就是Thread类中,获取当前线程名称方法)
System.out.println(getName() + " :好刺激哟,不行了,快、快。。" + j);
}
}
}
}
3、Future+线程池
jdk1.5+:
执行并处理返回值:
// 创建Future List
List<Future<List<SecOperatorVo>>> futureList = new ArrayList();
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
//多线程调用
for (final String postNo : postNoList) {
try {
futureList.add(executor.submit(new Callable<List<SecOperatorVo>>() {
@Override
public List<SecOperatorVo> call() throws Exception {
// 业务处理
// 这里返回是以 new 的形式,
return TomsQueryServiceImpl.this.getZJJZB(postNo);
}
}));
} catch (Exception e) {
log.error("捕获到一个线程调用时异常{}", e.getMessage());
}
}
executor.shutdown();
// 循环等待结束
while (!executor.isTerminated()) {
try {
// 等待200 毫秒
executor.awaitTermination(200, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
System.out.println(e);
log.error("线程等待异常", e);
}
}
//处理返回结果
for (Future<List<SecOperatorVo>> listFuture : futureList) {
List<SecOperatorVo> vos = listFuture.get();
}
4、CompletableFuture
jdk1.8+
无返回值:
@Test
public void testMultiThread() throws InterruptedException {
int i = 5;
System.out.println("=====多线程开始=====");
// 创建闭锁对象抓住所有线程,构造器指定倒数次数
CountDownLatch countDownLatch = new CountDownLatch(i);
while (i > 0) {
int finalI = i;
// 启用多线程
CompletableFuture.runAsync(() -> {
System.out.println(finalI);
// 线程执行结束则countDown,倒数一次
countDownLatch.countDown();
});
i--;
}
// 等待所有线程都countDown,倒数完毕,结束线程
countDownLatch.await();
System.out.println("=====多线程结束=====");
}
有返回值:
List<CompletableFuture<List<String>> completableFutureList = new ArrayList<>();
for (postMap spcpPostMap : postMapList) {//业务循环
//异步调用接口
CompletableFuture<List<String>> supplyAsync = CompletableFuture.supplyAsync(() ->
getData(),//业务方法调用
executorConfig.asyncServiceExecutor());//配置线程池,选填
completableFutureList.add(supplyAsync);
}
//处理结果
for (CompletableFuture<List<String>> completableFuture : completableFutureList) {
List<String> join = completableFuture.join();
for (String s: join) {
//业务代码
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class ExecutorConfig {
@Bean
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(5);
//配置最大线程数
executor.setMaxPoolSize(5);
//配置队列大小
executor.setQueueCapacity(99999);
//配置线程池中的线程的名称前缀
executor.setThreadNamePrefix("async-service-");
// rejection-policy:当pool已经达到max size的时候,如何处理新任务
// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}