首页
关于
友链
Search
1
wlop 4K 壁纸 4k8k 动态 壁纸
1,468 阅读
2
Nacos持久化MySQL问题-解决方案
932 阅读
3
Docker搭建Typecho博客
750 阅读
4
滑动时间窗口算法
728 阅读
5
Nginx反向代理微服务配置
699 阅读
生活
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
安全
开发工具
百度网盘
天翼网盘
阿里网盘
登录
Search
标签搜索
java
javase
docker
java8
springboot
thread
spring
分布式
mysql
锁
linux
redis
源码
typecho
centos
git
map
RabbitMQ
lambda
stream
少年
累计撰写
189
篇文章
累计收到
24
条评论
首页
栏目
生活
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
安全
开发工具
百度网盘
天翼网盘
阿里网盘
页面
关于
友链
搜索到
4
篇与
的结果
2022-11-20
JAVA8-多线程Future设计模式原理,自定义实现一个Future程序
JAVA8-多线程Future设计模式原理,自定义实现一个Future程序。自定义实现Future,理解设计模式原理。Future模式实现自定义代码示例:package com.example.study.java8.funture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; /** * 自定义模拟future,理解Future的使用。 */ public class FutureInAction { public static void main(String[] args) throws InterruptedException { Funture<String> funture = invoke(() -> { try { //模拟操作计算很长时间 Thread.sleep(10000); return "I'm finished"; } catch (Exception e) { e.printStackTrace(); return "Error"; } }); //操作计算很长时间,还没操作计算完成,只返回了future,虽然此时返回值为null,但是可以接着执行官其它操作,不会阻塞后续操作。 System.out.println(funture.get()); System.out.println(funture.get()); System.out.println(funture.get()); //知道操作计算完成后,将值返回 while (!funture.isDone()) { Thread.sleep(10); } System.out.println(funture.get()); } private static <T> Funture<T> invoke(Callable<T> callable) { AtomicReference<T> result = new AtomicReference<>(); AtomicBoolean finished = new AtomicBoolean(false); Thread t = new Thread(() -> { T value = callable.action(); result.set(value); finished.set(true); }); t.start(); Funture funture = new Funture() { @Override public Object get() { return result.get(); } @Override public boolean isDone() { return finished.get(); } }; return funture; } private interface Funture<T> { T get(); boolean isDone(); } private interface Callable<T> { T action(); } }输出结果:null //这里没有阻塞 null //这里没有阻塞 null //这里没有阻塞 I'm finished //这里没有阻塞null之前没有阻塞,可以之前后续的其它操作。用没有使用Future的方式实现package com.example.study.java8.funture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; /** * 自定义模拟future,理解Future的使用。 */ public class FutureInAction { public static void main(String[] args) throws InterruptedException { //以前没有future,阻塞方式测试 String str = block(() -> { try { //模拟操作计算很长时间 Thread.sleep(10000); return "I'm finished"; } catch (Exception e) { e.printStackTrace(); return "Error"; } }); //这里就会阻塞等返回结果,再执行下面的其他操作。 System.out.println(str); } //最早的没有future,实现方式 private static <T> T block(Callable<T> callable) { return callable.action(); } private interface Funture<T> { T get(); boolean isDone(); } private interface Callable<T> { T action(); } } 输出结果:I'm finished //这里会阻塞,等很久操作计算完成,才打印结果,后续的其它操作会被阻塞在这里这里会阻塞,等很久操作计算完成,才打印结果,后续的其它操作会被阻塞在这里。
2022年11月20日
134 阅读
0 评论
1 点赞
2022-03-19
ScheduledThreadPool线程调度
ScheduledThreadPool线程调度package com.yanxizhu; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /* * 一、线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。 * * 二、线程池的体系结构: * java.util.concurrent.Executor : 负责线程的使用与调度的根接口 * |--**ExecutorService 子接口: 线程池的主要接口 * |--ThreadPoolExecutor 线程池的实现类 * |--ScheduledExecutorService 子接口:负责线程的调度 * |--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService * * 三、工具类 : Executors * ExecutorService newFixedThreadPool() : 创建固定大小的线程池 * ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。 * ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程 * * ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务。 */ public class TestScheduledThreadPool { public static void main(String[] args) throws Exception { ScheduledExecutorService pool = Executors.newScheduledThreadPool(5); for (int i = 0; i < 5; i++) { Future<Integer> result = pool.schedule(new Callable<Integer>(){ @Override public Integer call() throws Exception { int num = new Random().nextInt(100);//生成随机数 System.out.println(Thread.currentThread().getName() + " : " + num); return num; } }, 1, TimeUnit.SECONDS); System.out.println(result.get()); } pool.shutdown(); } }
2022年03月19日
184 阅读
0 评论
5 点赞
2022-03-19
FutureTask用于闭锁
package com.yanxizhu; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * @description: FutureTask可用于闭锁 * @date: 2022/3/19 11:48 * @version: 1.0 */ public class FutureTaskDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { myFutureTask myFutureTask = new myFutureTask(); FutureTask<Integer> futureTask = new FutureTask<>(myFutureTask); new Thread(futureTask).start(); //必须等线程执行完,才执行下面的代码,因此FutureTask可用于闭锁 Integer integer = futureTask.get(); System.out.println("integer="+integer); System.out.println("======================="); } public static class myFutureTask implements Callable<Integer>{ @Override public Integer call() throws Exception { int i=1; for(;i<1000000;i++){ i++; } return i; } } }
2022年03月19日
156 阅读
0 评论
5 点赞
2022-03-10
JAVA多线程4种实现方式
异步与线程池1、初始化线程的4种方式1)、继承Thread2)、实现Runnable接口3)、实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)4)、线程池方式1和方式2:主进程无法获取线程的运算结果。不适合当前场景。方式3:主进程可以获取线程的运算结果,但是不利于控制服务器中的线程资源。可以导致服务器资源耗尽。方式4:通过如下两种方式初始化线程池Executors.newFiexed ThreadPool(3); //或者 new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit unit, workQueue,threadFactory,handler);方式1、继续Thread/** * @description: 继承Thread * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/3/10 21:06 * @version: 1.0 */ public class MyThread { public static void main(String[] args) { System.out.println("启动main方法开始"); OneMyThread oneMyThread = new OneMyThread(); oneMyThread.start(); System.out.println("结束main方法"); } public static class OneMyThread extends Thread{ @Override public void run() { System.out.println("当前线程:"+Thread.currentThread().getId()); int i = 10/2; System.out.println("运行结果:"+i); } } }运行结果:启动main方法开始 结束main方法 当前线程:22 运行结果:5方式2、实现Runable接口/** * @description: 实现Runnable接口 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/3/10 21:06 * @version: 1.0 */ public class MyThread { public static void main(String[] args) { System.out.println("启动main方法开始"); TwoMyThread twoMyThread = new TwoMyThread(); new Thread(twoMyThread).start(); System.out.println("结束main方法"); } /** * 实现Runnable接口 */ public static class TwoMyThread implements Runnable { @Override public void run() { System.out.println("当前线程:"+Thread.currentThread().getId()); int i = 10/2; System.out.println("运行结果:"+i); } } }运行结果:启动main方法开始 结束main方法 当前线程:22 运行结果:5方式3、实现Callable泛型接口/** * @description: 继承Thread * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/3/10 21:06 * @version: 1.0 */ public class MyThread { public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("启动main方法开始"); FutureTask<Integer> futureTask = new FutureTask<>(new ThreeMyThread()); new Thread(futureTask).start(); //等待线程执行完成,返回结果 Integer i = futureTask.get(); System.out.println("线程执行完,返回结果:"+i); System.out.println("结束main方法"); } /** * 实现Callable<T>泛型接口 */ public static class ThreeMyThread implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("当前线程:"+Thread.currentThread().getId()); int i = 10/2; System.out.println("运行结果:"+i); return i; } } }运行结果:启动main方法开始 当前线程:22 运行结果:5 线程执行完,返回结果:5 结束main方法注意:结果的顺序,可以看到是一个阻塞等待通过FutureTask类源码可以看到,FutureTask不仅可以接受Callable还可以接收Runnable.FutureTask源码如下:public class FutureTask<V> implements RunnableFuture<V> { /** * Creates a {@code FutureTask} that will, upon running, execute the * given {@code Runnable}, and arrange that {@code get} will return the * given result on successful completion. * * @param runnable the runnable task * @param result the result to return on successful completion. If * you don't need a particular result, consider using * constructions of the form: * {@code Future<?> f = new FutureTask<Void>(runnable, null)} * @throws NullPointerException if the runnable is null */ public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable }FutureTask实现RunnableFuture接口:RunnableFuture最终是继承的Runnable。package java.util.concurrent; /** * A {@link Future} that is {@link Runnable}. Successful execution of * the {@code run} method causes completion of the {@code Future} * and allows access to its results. * @see FutureTask * @see Executor * @since 1.6 * @author Doug Lea * @param <V> The result type returned by this Future's {@code get} method */ public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }方式4、直接提交线程池,线程池会自动开启任务。每次通过new Thread()创建线程问题:导致资源耗尽。以上三种启动方式都不用。应该将所有异步多线程任务交给线程池执行。线程池:package com.yanxizhu.family.booking; import java.util.concurrent.*; /** * @description: 继承Thread * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/3/10 21:06 * @version: 1.0 */ public class MyThread { //应保证,当前系统中线程池只有一两个,每个异步任务,提交给线程池自己执行。 public static ExecutorService executorService = Executors.newFixedThreadPool(10); public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("启动main方法开始"); executorService.submit(new TwoMyThread()); //有返回值 //每个异步任务,提交给线程池自己执行。 executorService.execute(new TwoMyThread());//无返回值 System.out.println("结束main方法"); } /** * 实现Runnable接口 */ public static class TwoMyThread implements Runnable { @Override public void run() { System.out.println("当前线程:"+Thread.currentThread().getId()); int i = 10/2; System.out.println("运行结果:"+i); } } } 运行结果:启动main方法开始 结束main方法 当前线程:22 运行结果:5使用线程池带来的好处:1、降低资源的消耗通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗2、提高响应速度因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行3、提高线程的可管理性线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配总结区别1、直接继承Thread、实现Runnable接口:不能直接得到返回值。2、实现Callable泛型接口:可以得到返回值。3、继承Thread、实现Runnable接口、实现Callable泛型接口,都不能达到控制资源的效果。4、只有线程池可以控制资源,性能稳定。
2022年03月10日
171 阅读
0 评论
1 点赞