多线程,可以先看下小编总结的多线程(一)基础篇
==>文章入口
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//当前系统中只有一俩个池子。每个异步任务,提交给线程池他自己执行就行
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("main...start...");
//方式1继承Thread 启动线程
Thread01 thread = new Thread01();
thread.start();
System.out.println("============================");
//方式2实现Runnable接口 启动线程
Runnable01 runnable01 = new Runnable01();
new Thread(runnable01).start();
System.out.println("============================");
//方式3、实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常) 启动线程
// 注:FutureTask里面也能放Runnable
FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
new Thread(futureTask).start();
Integer result = futureTask.get();//阻塞等待--等待整个线程执行完成,获取返回结果
System.out.println("最后的返回结果:" + result);
System.out.println("============================");
//方式4 Executors创建线程池执行 Runnable01任务
execute.execute(new Runnable01());
System.out.println("main...end...");
}
public static class Thread01 extends Thread {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("继承Thread...运行结果:" + i);
}
}
public static class Runnable01 implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("实现Runnable接口...运行结果:" + i);
}
}
public static class Callable01 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("实现 Callable 接口 + FutureTask...运行结果:" + i);
return i;
}
}
public static class Runnable04 implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("线程池放Runnable04...运行结果:" + i);
}
}
}
运行结果:
main...start...
============================
当前线程:12
继承Thread...运行结果:5
============================
当前线程:13
实现Runnable接口...运行结果:5
当前线程:14
实现 Callable 接口 + FutureTask...运行结果:5
最后的返回结果:5
============================
main...end...
当前线程:15
实现Runnable接口...运行结果:5
方式1、2 不能得到返回值。3可以获取返回值
方式1、2、3 都不能控制资源
方式4 可以控制资源,性能稳定。
在业务场景,以上3种方式启动线程都不使用。会导致资源耗尽。
将所有多线程异步任务都交给线程池执行
线程池的7大参数:
01、int corePoolSize: 核心线程数(一直存在,除非allowCoreThreadTimeOut)。
线程池,创建好以后就准备就绪的线程数量,就等待接收异步任务来执行
例如:corePoolSize:[5] 等于 5个 Thread thread = new Thread()
02、int maximumPoolSize: 最大线程数量。控制资源
03、long keepAliveTime: 存活时间。如果当前的线程数量大于核心数量(corePoolSize)
释放空闲的线程(maximumPoolSize - corePoolSize)。
只要线程空闲大于指定的keepAliveTime,就会释放
04、TimeUnit unit: 时间单位
05、BlockingQueue<Runnable> workQueue: 阻塞队列。
如果任务有很多,就会将目前多的任务放在队列里面
只要有线程空闲,就会去队列里面取出新的任务执行
06、ThreadFactory threadFactory: 线程的创建工厂
07、RejectedExecutionHandler handler: 拒绝策略
如果队列满了,按照我们指定的拒绝策略拒绝执行任务
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
public static void main(String[] args) throws Exception {
/**
* new LinkedBlockingDeque<>():默认是Integer的最大值。容易导致内存不够。
* 要指定数量,例如: new LinkedBlockingDeque<>(10000)
*/
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
200,
10,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(10000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
executor.execute(new Runnable05());
}
public static class Runnable05 implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("线程池放Runnable05...运行结果:" + i);
}
}
}
一个线程池 core 7; max 20 ,queue:50,100 并发进来怎么分配的?
先有 7 个能直接得到执行,接下来 50 个进入队列排队,在多开 13 个继续执行。
现在 70 个被安排上了。剩下 30 个默认拒绝策略
如果不想抛弃还要执行。使用CallerRunsPolicy策略。会同步执行
或者将最老的,一直不执行的丢弃
单线程的线程池应用说明:
应用场景:分布式的情况下,保证双写一致的情况,需要将同样的业务留给同一台服务器或者线程来执行处理
//大小为10
ExecutorService execute = Executors.newFixedThreadPool(10);
//执行
execute.execute(new Runnable01());//看创建多线程的4种方式(回顾)里面的第4种
在 Java 8 中, 新增加了一个包含 50 个方法左右的类: CompletableFuture,提供了非常强大的
Future 的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以
通过回调的方式处理计算结果,并且提供了转换和组合 CompletableFuture 的方法。
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
//可以传入自定义的线程池,否则就用默认的线程池;
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("main...start...");
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
}, execute);
System.out.println("main...end...");
}
}
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("main...start...");
//可以传入自定义的线程池,否则就用默认的线程池;
//第二种:supplyAsync的whenComplete
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, execute);
Integer res = future.get();
System.out.println("返回值:"+res);
System.out.println("main...start...");
}
}
方法执行完成后的感知==>whenComplete
方法执行完成后的处理==>handle
只能感知异常,无法修改返回的数据
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("main...start...");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
// int i = 10 / 0;//制造异常
System.out.println("运行结果:" + i);
return i;
}, execute).whenComplete((result,exception)->{
//【whenComplete缺点只能感知】
//感知异常,但是没法修改返回数据
System.out.println("异步任务执行完成了。。。结果是:"+result+" "+"异常是:"+exception);
}).exceptionally(throwable -> {
//可以感知异常,同事返回默认值
return 10;//出现异常返回10
});
System.out.println("main...start...");
}
}
处理完在返回
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("main...start...");
//第二种:supplyAsync的handle
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, execute).handle((result, exception) -> {
if (result != null) {
return result * 50;
}
if (exception != null) {
return 0;
}
return 0;
});
Integer returnResult = future.get();
System.out.println("返回的结果:"+returnResult);
System.out.println("main...start...");
}
}
thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值
thenAccept 方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果。
thenRun 方法:只要上面的任务执行完成,就开始执行 thenRun,只是处理完任务后,执行thenRun 的后续操作带有 Async 默认是异步执行的。 同之前。以上都要前置任务成功完成。
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
//thenRunAsync
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, execute).thenRunAsync(() -> {
//模拟第二个线程任务
System.out.println("任务2启动了。。。模拟第二个线程任务");
}, execute);
System.out.println("============main...start...===============");
}
}
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
//thenAcceptAsync
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("运行结果:" + i);
return i;
}, execute).thenAcceptAsync(result -> {
//模拟第二个线程任务,拿到上一个线程的处理结果,继续线程操作
System.out.println("任务2启动了《模拟第二个线程任务,拿到上一个线程的处理结果,继续线程操作》..上一次的结果:" + result);
}, execute);
System.out.println("============main...start...===============");
}
}
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 10 / 2;
System.out.println("任务1=运行结果:" + i);
return i;
}, execute).thenApplyAsync((result) -> {
System.out.println("任务2启动了《模拟第二个线程任务,拿到上一个线程的处理结果,继续线程操作》..上一次的结果:" + result);
return "Hello " + result;
}, execute);
String s = future.get();
System.out.println("有返回值!!!==>最后的返回值:"+s);
System.out.println("============main...start...===============");
}
}
thenCombine
:组合两个 future,获取两个 future 的返回结果,并返回当前任务的返回值thenAcceptBoth
:组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有返回值。runAfterBoth
:组合两个 future,不需要获取 future 的结果,只需两个 future 处理完任务后,import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 俩个都完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
//第一种 runAfterBothAsync无法感知前面俩个的结果
future01.runAfterBothAsync(future02,()->{
//线程1组合线程2,都完成以后开始任务3
System.out.println("任务3开始");
},execute);
// //第二种 thenAcceptBothAsync能感知前面的结果
// future01.thenAcceptBothAsync(future02,(f1,f2)->{
// System.out.println("任务3开始");
// System.out.println("任务1的返回值:"+f1);
// System.out.println("任务2的返回值:"+f2);
// },execute);
// //第三种 thenCombineAsync能感知前面的结果,自己有返回值
// CompletableFuture future03 = future01.thenCombineAsync(future02, (f1, f2) -> {
// System.out.println("任务3开始");
// return f1 + ":" + f2 + "我是任务3的返回";
// }, execute);
// String s = future03.get();
// System.out.println(s);
System.out.println("============main...start...===============");
}
}
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 俩个都完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
// //第一种 runAfterBothAsync无法感知前面俩个的结果
// future01.runAfterBothAsync(future02,()->{
// //线程1组合线程2,都完成以后开始任务3
// System.out.println("任务3开始");
// },execute);
//第二种 thenAcceptBothAsync能感知前面的结果
future01.thenAcceptBothAsync(future02,(f1,f2)->{
System.out.println("任务3开始");
System.out.println("任务1的返回值:"+f1);
System.out.println("任务2的返回值:"+f2);
},execute);
// //第三种 thenCombineAsync能感知前面的结果,自己有返回值
// CompletableFuture future03 = future01.thenCombineAsync(future02, (f1, f2) -> {
// System.out.println("任务3开始");
// return f1 + ":" + f2 + "我是任务3的返回";
// }, execute);
// String s = future03.get();
// System.out.println(s);
System.out.println("============main...start...===============");
}
}
package com.atguigu.gulimall.product;
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 俩个都完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
// //第一种 runAfterBothAsync无法感知前面俩个的结果
// future01.runAfterBothAsync(future02,()->{
// //线程1组合线程2,都完成以后开始任务3
// System.out.println("任务3开始");
// },execute);
// //第二种 thenAcceptBothAsync能感知前面的结果
// future01.thenAcceptBothAsync(future02,(f1,f2)->{
// System.out.println("任务3开始");
// System.out.println("任务1的返回值:"+f1);
// System.out.println("任务2的返回值:"+f2);
// },execute);
//第三种 thenCombineAsync能感知前面的结果,自己有返回值
CompletableFuture<String> future03 = future01.thenCombineAsync(future02, (f1, f2) -> {
System.out.println("任务3开始");
return f1 + ":" + f2 + "我是任务3的返回";
}, execute);
String s = future03.get();
System.out.println(s);
System.out.println("============main...start...===============");
}
}
俩个任务,只要有一个完成,就执行任务3
package com.atguigu.gulimall.product;
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 来个任务,任意一个完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
//第一种 runAfterEitherAsync
future01.runAfterEitherAsync(future02,()->{
System.out.println("任务3开始");
},execute);
// //第二种 acceptEitherAsync==>[任务1和任务2的返回值类型必须一致]
// future01.acceptEitherAsync(future02,(res)->{
// System.out.println("任务3开始..."+"之前的线程1的结果:"+res);
// },execute);
//
// //第三种 applyToEitherAsync
// CompletableFuture future03 = future01.applyToEitherAsync(future02, (res) -> {
// System.out.println("任务3开始..." + "之前的线程1的结果:" + res);
// return res.toString() + "-->hello";
// }, execute);
// String f3 = future03.get();
// System.out.println("f3:"+f3);
System.out.println("============main...start...===============");
}
}
package com.atguigu.gulimall.product;
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 来个任务,任意一个完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
// //第一种 runAfterEitherAsync
// future01.runAfterEitherAsync(future02,()->{
// System.out.println("任务3开始");
// },execute);
//第二种 acceptEitherAsync==>[任务1和任务2的返回值类型必须一致]
future01.acceptEitherAsync(future02,(res)->{
System.out.println("任务3开始..."+"之前的线程1的结果:"+res);
},execute);
// //第三种 applyToEitherAsync
// CompletableFuture future03 = future01.applyToEitherAsync(future02, (res) -> {
// System.out.println("任务3开始..." + "之前的线程1的结果:" + res);
// return res.toString() + "-->hello";
// }, execute);
// String f3 = future03.get();
// System.out.println("f3:"+f3);
System.out.println("============main...start...===============");
}
}
package com.atguigu.gulimall.product;
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 来个任务,任意一个完成
*/
CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务1线程:" + Thread.currentThread().getId());
int i = 10 / 5;
System.out.println("任务1结束");
return i;
}, execute);
CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
System.out.println("任务2线程:" + Thread.currentThread().getId());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务2结束");
return "Hello";
}, execute);
// //第一种 runAfterEitherAsync
// future01.runAfterEitherAsync(future02,()->{
// System.out.println("任务3开始");
// },execute);
// //第二种 acceptEitherAsync==>[任务1和任务2的返回值类型必须一致]
// future01.acceptEitherAsync(future02,(res)->{
// System.out.println("任务3开始..."+"之前的线程1的结果:"+res);
// },execute);
// //第三种 applyToEitherAsync
CompletableFuture<String> future03 = future01.applyToEitherAsync(future02, (res) -> {
System.out.println("任务3开始..." + "之前的线程1的结果:" + res);
return res.toString() + "-->hello";
}, execute);
String f3 = future03.get();
System.out.println("f3:"+f3);
System.out.println("============main...start...===============");
}
}
package com.atguigu.gulimall.product;
import java.util.concurrent.*;
/**
* @author suqinyi
* @Date 2021/8/22
*/
public class Thread4Test {
//自定义的线程池
public static ExecutorService execute = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
System.out.println("===========main...start...===============");
/**
* 多任务组合
*/
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询物品的图片信息1");
return "hello.jpg";
},execute);
CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询物品的属性2");
return "蓝色+256G";
},execute);
CompletableFuture<String> futureDesc= CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("查询物品的介绍3");
return "介绍=价格998";
},execute);
//1、allOf
CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
//allOf.join();//插队---get或者join都行
allOf.get();//等待所有结果完成--->最后的一句话最后打印.阻塞住==>就是这个 System.out.println("============main...start...===============");
System.out.println("futureImg:"+futureImg.get()+"..."+"futureAttr:"+futureAttr.get()+"..."+"futureDesc:"+futureDesc.get());
// //2、anyOf
// CompletableFuture
// Object o = anyOf.get();
// System.out.println("anyOf:"+o);
System.out.println("============main...start...===============");
}
}