CompletableFuture和FutureTask

CompletableFutureFutureTask,和它们的API方法的功能介绍

CompletableFuture

CompletableFuture是Java 8引入的一个强大的类,用于处理异步编程。它实现了Future接口,并提供了多种方法来处理异步计算的结果。

创建CompletableFuture对象的方法:
  1. supplyAsync(Supplier<U> supplier): 使用默认的ForkJoinPool异步执行一个任务。
  2. supplyAsync(Supplier<U> supplier, Executor executor): 使用指定的Executor异步执行一个任务。
  3. runAsync(Runnable runnable): 使用默认的ForkJoinPool异步执行一个Runnable任务。
  4. runAsync(Runnable runnable, Executor executor): 使用指定的Executor异步执行一个Runnable任务。
  5. completedFuture(U value): 返回一个已经完成的CompletableFuture
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureExample {
    public static void main(String[] args) {
        // 使用默认的ForkJoinPool执行任务
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
        
        // 创建自定义的Executor执行任务
        ExecutorService executor = Executors.newFixedThreadPool(2);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Hello", executor);
        
        // 使用Runnable执行任务
        CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> System.out.println("Runnable executed"));
        
        // 使用自定义的Executor执行Runnable任务
        CompletableFuture<Void> future4 = CompletableFuture.runAsync(() -> System.out.println("Runnable executed"), executor);
        
        // 返回已经完成的CompletableFuture
        CompletableFuture<String> completedFuture = CompletableFuture.completedFuture("Already completed");
        
        executor.shutdown();
    }
}
组合和处理异步计算结果的方法:
  1. thenApply(Function<? super T,? extends U> fn): 在当前CompletableFuture完成后,执行函数并返回一个新的CompletableFuture
  2. thenAccept(Consumer<? super T> action): 在当前CompletableFuture完成后,执行消费函数,不返回结果。
  3. thenRun(Runnable action): 在当前CompletableFuture完成后,执行一个Runnable。
  4. thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn): 在两个CompletableFuture都完成后,执行一个函数,并返回一个新的CompletableFuture
  5. thenCompose(Function<? super T,? extends CompletionStage<U>> fn): 在当前CompletableFuture完成后,执行函数返回另一个CompletionStage
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 异步计算,返回 "Hello"
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello";
        });

        // thenApply: 在future完成后执行
        CompletableFuture<String> resultFuture = future.thenApply(result -> result + " World");

        // thenAccept: 在future完成后执行,无返回值
        future.thenAccept(result -> System.out.println("Result: " + result));

        // thenRun: 在future完成后执行,无参数和返回值
        future.thenRun(() -> System.out.println("Computation finished."));

        // thenCombine: 组合两个future的结果
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> " World");
        CompletableFuture<String> combinedFuture = future.thenCombine(future2, (res1, res2) -> res1 + res2);
        System.out.println(combinedFuture.get()); // 输出 "Hello World"

        // thenCompose: 组合两个异步任务
        CompletableFuture<String> composedFuture = future.thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " World"));
        System.out.println(composedFuture.get()); // 输出 "Hello World"
    }
}
处理异常的方法:
  1. handle(BiFunction<? super T, Throwable, ? extends U> fn): 处理正常和异常结果。
  2. exceptionally(Function<Throwable, ? extends T> fn): 处理异常情况,并返回一个默认值。
  3. whenComplete(BiConsumer<? super T, ? super Throwable> action): 在CompletableFuture完成后(正常或异常)执行一个操作。
import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        // 异步计算,随机抛出异常
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            if (Math.random() > 0.5) {
                throw new RuntimeException("Failed");
            }
            return "Success";
        });

        // handle: 处理正常和异常结果
        CompletableFuture<String> handledFuture = future.handle((result, ex) -> {
            if (ex != null) {
                return "Error: " + ex.getMessage();
            }
            return result;
        });
        System.out.println(handledFuture.join()); // 处理并打印结果

        // exceptionally: 处理异常情况
        CompletableFuture<String> exceptionalFuture = future.exceptionally(ex -> "Error: " + ex.getMessage());
        System.out.println(exceptionalFuture.join()); // 处理并打印异常

        // whenComplete: 在完成后执行操作
        future.whenComplete((result, ex) -> {
            if (ex != null) {
                System.out.println("Completed with error: " + ex.getMessage());
            } else {
                System.out.println("Completed with result: " + result);
            }
        });
    }
}
其他常用方法:
  1. complete(T value): 手动完成CompletableFuture并设置结果。
  2. join(): 与get()类似,但不抛出受检异常。
  3. allOf(CompletableFuture<?>... cfs): 等待所有提供的CompletableFuture完成。
  4. anyOf(CompletableFuture<?>... cfs): 等待任意一个提供的CompletableFuture完成。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建一个未完成的CompletableFuture
        CompletableFuture<String> future = new CompletableFuture<>();
        
        // 手动完成
        future.complete("Manually completed");
        System.out.println(future.get()); // 输出 "Manually completed"
        
        // join: 获取结果,无需处理异常
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Hello");
        System.out.println(future2.join()); // 输出 "Hello"
        
        // allOf: 等待所有提供的CompletableFuture完成
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "Task 1");
        CompletableFuture<String> future4 = CompletableFuture.supplyAsync(() -> "Task 2");
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future3, future4);
        allOfFuture.thenRun(() -> System.out.println("All tasks completed")).join(); // 等待所有任务完成并打印
        
        // anyOf: 等待任意一个提供的CompletableFuture完成
        CompletableFuture<String> future5 = CompletableFuture.supplyAsync(() -> "Task 3");
        CompletableFuture<String> future6 = CompletableFuture.supplyAsync(() -> "Task 4");
        CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future5, future6);
        System.out.println("Any task completed: " + anyOfFuture.join()); // 输出任意一个任务完成的结果
    }
}

FutureTask

FutureTaskFutureRunnable的一个具体实现,它可以包装一个CallableRunnable,并且可以直接在线程中执行。

创建FutureTask对象的方法:
  1. 构造函数FutureTask(Callable<V> callable): 包装一个Callable
  2. 构造函数FutureTask(Runnable runnable, V result): 包装一个Runnable
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建Callable
        Callable<String> callable = () -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Callable Result";
        };

        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask1 = new FutureTask<>(callable);

        // 创建Runnable
        Runnable runnable = () -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
                System.out.println("Runnable executed");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        // 创建FutureTask并包装Runnable
        FutureTask<String> futureTask2 = new FutureTask<>(runnable, "Runnable Result");

        // 使用线程执行FutureTask
        Thread thread1 = new Thread(futureTask1);
        Thread thread2 = new Thread(futureTask2);

        thread1.start();
        thread2.start();

        // 获取结果
        System.out.println("FutureTask1 result: " + futureTask1.get()); // 输出 "Callable Result"
        System.out.println("FutureTask2 result: " + futureTask2.get()); // 输出 "Runnable Result"
    }
}
FutureTask 的主要方法
  1. run()
  • 执行任务。如果任务已经完成或者被取消,那么这个方法不会有任何效果。
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();
    }
}
  1. get()
  • 阻塞等待任务完成并返回结果。
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();

        // 获取结果
        String result = futureTask.get();
        System.out.println(result); // 输出 "Task completed"
    }
}
  1. get(long timeout, TimeUnit unit)
  • 在指定时间内等待任务完成并返回结果,如果超时则抛出TimeoutException
import java.util.concurrent.*;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();

        try {
            // 获取结果,超时会抛出TimeoutException
            String result = futureTask.get(500, TimeUnit.MILLISECONDS);
            System.out.println(result);
        } catch (TimeoutException e) {
            System.out.println("Task timed out");
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}
  1. cancel(boolean mayInterruptIfRunning)
  • 取消任务。如果任务还未开始执行,任务将被取消。如果任务已经开始执行,并且mayInterruptIfRunningtrue,则任务会被中断。
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();

        // 尝试取消任务
        boolean cancelled = futureTask.cancel(true);
        System.out.println("Cancelled: " + cancelled);
    }
}
  1. isCancelled()
  • 如果任务被取消,则返回true
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();

        // 取消任务
        futureTask.cancel(true);

        // 检查任务是否被取消
        boolean isCancelled = futureTask.isCancelled();
        System.out.println("Is cancelled: " + isCancelled); // 输出 "Is cancelled: true"
    }
}
  1. isDone()
  • 如果任务已经完成,无论是正常完成还是被取消,返回true
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask = new FutureTask<>(() -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Task completed";
        });

        // 创建并启动线程
        Thread thread = new Thread(futureTask);
        thread.start();

        // 检查任务是否完成
        boolean isDone = futureTask.isDone();
        System.out.println("Is done: " + isDone); // 输出 "Is done: false"
    }
}

完整示例

CompletableFuture 示例
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建自定义的Executor执行任务
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // supplyAsync: 异步执行任务
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello";
        }, executor);

        // thenApply: 在future完成后执行函数并返回新future
        CompletableFuture<String> resultFuture = future.thenApply(result -> result + " World");

        // thenAccept: 在future完成后执行消费函数
        resultFuture.thenAccept(result -> System.out.println("Result: " + result)); // 输出 "Result: Hello World"

        // handle: 处理正常和异常结果
        CompletableFuture<String> handledFuture = resultFuture.handle((result, ex) -> {
            if (ex != null) {
                return "Error: " + ex.getMessage();
            }
            return result;
        });
        System.out.println(handledFuture.join()); // 输出 "Hello World"

        // complete: 手动完成future
        future.complete("Manually completed");
        System.out.println(future.get()); // 输出 "Manually completed"

        // allOf: 等待所有提供的CompletableFuture完成
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Task 1", executor);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "Task 2", executor);
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(future1, future2);
        allOfFuture.thenRun(() -> System.out.println("All tasks completed")).join(); // 等待所有任务完成并打印

        // anyOf: 等待任意一个提供的CompletableFuture完成
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> "Task 3", executor);
        CompletableFuture<String> future4 = CompletableFuture.supplyAsync(() -> "Task 4", executor);
        CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(future3, future4);
        System.out.println("Any task completed: " + anyOfFuture.join()); // 输出任意一个任务完成的结果

        executor.shutdown();
    }
}
FutureTask 示例
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskExample {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建Callable
        Callable<String> callable = () -> {
            Thread.sleep(1000); // 模拟耗时操作
            return "Callable Result";
        };

        // 创建FutureTask并包装Callable
        FutureTask<String> futureTask1 = new FutureTask<>(callable);

        // 创建Runnable
        Runnable runnable = () -> {
            try {
                Thread.sleep(1000); // 模拟耗时操作
                System.out.println("Runnable executed");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        // 创建FutureTask并包装Runnable
        FutureTask<String> futureTask2 = new FutureTask<>(runnable, "Runnable Result");

        // 使用线程执行FutureTask
        Thread thread1 = new Thread(futureTask1);
        Thread thread2 = new Thread(futureTask2);

        thread1.start();
        thread2.start();

        // 获取结果
        System.out.println("FutureTask1 result: " + futureTask1.get()); // 输出 "Callable Result"
        System.out.println("FutureTask2 result: " + futureTask2.get()); // 输出 "Runnable Result"

        // 取消任务示例
        FutureTask<String> futureTask3 = new FutureTask<>(() -> {
            Thread.sleep(2000); // 模拟耗时操作
            return "Task completed";
        });

        Thread thread3 = new Thread(futureTask3);
        thread3.start();

        // 尝试取消任务
        boolean cancelled = futureTask3.cancel(true);
        System.out.println("Cancelled: " + cancelled); // 输出 "Cancelled: true"

        // 检查任务是否被取消
        boolean isCancelled = futureTask3.isCancelled();
        System.out.println("Is cancelled: " + isCancelled); // 输出 "Is cancelled: true"

        // 检查任务是否完成
        boolean isDone = futureTask3.isDone();
        System.out.println("Is done: " + isDone); // 输出 "Is done: true"
    }
}

综述

CompletableFuture 和 FutureTask 的对比
  1. CompletableFuture

    • 功能更强大:支持链式调用、组合、处理异常等高级功能。
    • 异步支持:非常适合异步编程,提供了丰富的API来处理异步计算结果。
    • 易用性:使用方便,支持流式API,非常适合复杂的异步工作流。
  2. FutureTask

    • 基础性:功能较简单,主要用来包装RunnableCallable
    • 同步调用:需要手动启动线程来执行任务。
    • 控制:提供对任务的取消、完成等基本控制。
CompletableFuture 的常用 API 总结
  • 创建:supplyAsyncrunAsynccompletedFuture
  • 组合:thenApplythenAcceptthenRunthenCombinethenCompose
  • 异常处理:handleexceptionallywhenComplete
  • 其他:completejoinallOfanyOf
FutureTask 的常用 API 总结
  • 创建:FutureTask(Callable<V> callable)FutureTask(Runnable runnable, V result)
  • 操作:rungetcancelisCancelledisDone

这些API提供了灵活的异步编程和任务控制机制,使得在Java中进行并发编程变得更加简便和高效。通过合理使用这些工具,可以大大提高程序的性能和响应能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/770273.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

zabbix报警机制,主动监控

zabbix思路流程 主动监控 默认zabbix使用的是被动监控&#xff0c;主被动监控都是针对被监控主机而言的。被动监控&#xff1a;Server向Agent发起请求&#xff0c;索取监控数据。此种模式常用主动监控&#xff1a;Agent向Server发起连接&#xff0c;向Server汇报 配置web2使用…

实验五 数据库完整性约束的实现与验证

题目 在实验四的基础上&#xff0c;重新创建以下三个表&#xff1a; 会员表&#xff1a;member(memno,memname,address,telephone,username,userpwd)&#xff0c;主码为memno&#xff0c;属性memname不能取空值 员工表&#xff1a;employee(empno,empname,depno,sex,telephone…

Go语言工程管理

本文内容为Go工程创建和配置开发及简单程序示例。 目录 工程管理 GOPATH 配置GOPATH GOROOT 新建系统变量 配置go工程 添加go path 简单的程序实现 程序代码 开始运行 运行结果 内容解析 总结 工程管理 GOPATH go语言的项目&#xff0c;需要有特定的目录结构进行…

ArmPiPro-环境变量

V0.0 2024-07-04 V0.1 加入开发环境和PI4关于ROS的环境变量的对比 1.我们可以用env | grep ROS来查看Pi4中的ROS环境变量 如下图所示&#xff0c;不理解的&#xff0c;抛给AI快速了解一下。 2.ArmPiPro安装的ROS是ROS1-melodic 3.在开发时&#xff0c;需要在笔记本电脑上开一…

visual studio远程调试

场景一&#xff08;被远程调试的电脑&#xff09; 确定系统位数 我这里是x64的 找到msvsmon.exe msvsmon.exe目录位置解释&#xff1a; “F:\App\VisualStudio\an\Common7\IDE\”是visual studio所在位置、 “Remote Debugger\”是固定位置、 “x64”是系统位数。 拼起来就是…

uni-app上传失败超出文件限制解决方法-分包处理-预加载

分包背景 当你的上传出现一下错误&#xff1a; Error: 系统错误&#xff0c;错误码&#xff1a;80051,source size 2089KB exceed max limit 2MB [20240703 10:53:06][wxbf93dfb6cb3eb8af] [1.06.2405010][win32-x64] 说明你主包太大需要处理了&#xff0c;一下两种方法可以…

【LeetCode:841. 钥匙和房间 + DFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

嵌入式Linux系统编程 — 6.4 信号集

目录​​​​​​​ 1 信号集概念 2 sigemptyset、sigfillset初始化信号集 3 sigaddset、sigdelset向信号集中添加/删除信号 4 sigismember函数测试信号是否在信号集中 1 信号集概念 在Linux系统中&#xff0c;信号集&#xff08;signal set&#xff09;用于表示一组信号…

001:开源交易系统开发实战开篇

本专栏采用融入【主力思维】的方法学&#xff0c;包含数据抓取、特征模型开发、历史验证回归测试、每日动态风险评估管理等技术&#xff0c;较大的增强股票投资胜率&#xff0c;让IT开发者拥有一套实用的属于自己思路的专用交易软件。 先简要介绍下系统运行的成果和项目架构&a…

java版本ERP管理系统源码 Spring Cloud ERP_ERP系统_erp软件_ERP管理系统

在当今数字化时代&#xff0c;企业对高效、稳定且易于扩展的管理系统的需求日益增长。为了满足这一需求&#xff0c;我们精心打造了一款基于Java技术的ERP&#xff08;Enterprise Resource Planning&#xff09;管理系统。该系统充分利用了Spring Cloud Alibaba、Spring Boot、…

基于Java中的SSM框架实现小型企业人事管理系统项目【项目源码+论文说明】

基于Java中的SSM框架实现小型企业人事管理系统演示 摘要 人才是企业发展的核心力量&#xff0c;所以人事管理是企业管理中一项重要的任务。传统的人事管理系统不仅效率慢而且极易出错&#xff0c;使管理者不能清楚的了解每一位员工的详细情况&#xff0c;对企业的发展形成了不…

ctfshow-web入门-命令执行(web119、web120、web121、web122)

目录 1、web119 2、web120 3、web121 4、web122 1、web119 采用 118 的 payload&#xff0c;回显 evil input&#xff0c;说明新增了过滤 单独测试一下&#xff0c;是 PATH 、BASH 被过滤了 在上一题的基础上&#xff0c;我们再介绍一个内置变量&#xff1a;$RANDOM 它会…

【日记】居然梦到了南通……(701 字)

正文 昨晚的睡眠质量很不好。做了一个很离谱的梦&#xff0c;噩梦。梦到我被一群南通给那什么了。当时直接给我吓醒了。我都不知道为什么会做这种诡异的梦。 昨晚那群孩子要去这个县里最繁华的广场跳舞。结果老师一声 “走&#xff01;” 给我都听懵了。那地方可不近啊。我们最…

化身成羊:关于羊的词群探析

在西方的神话故事中&#xff0c;像主神宙斯&#xff0c;或者基督教义中的上帝&#xff0c;通常都有化身成羊的形象。 那为什么会这样呢&#xff1f; 一、什么是神话(myth)&#xff1f; 神话&#xff0c;正式的用词是 mythology&#xff1a; mythology n.神话&#xff1b;神话…

专访ATFX首席战略官Drew Niv:以科技创新引领企业高速发展

在金融科技创新的浪潮中&#xff0c;人才是推动企业高速发展的核心驱动力&#xff0c;优质服务是引领企业急速前行的灯塔。作为差价合约领域的知名品牌&#xff0c;ATFX高度重视人才引进工作&#xff0c;秉持“聚天下英才而用之”的理念&#xff0c;在全球范围内广揽科技精英&a…

java版本工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统

工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的…

二氯二氰苯醌(DDQ)市场空间受限 行业需要寻求新的发展方向及机遇

二氯二氰苯醌&#xff08;DDQ&#xff09;市场空间受限 行业需要寻求新的发展方向及机遇 二氯二氰苯醌&#xff08;DDQ&#xff09;&#xff0c;学名2,3-二氯-5,6-二氰基苯醌&#xff0c;是一种亮黄色粉末状化合物&#xff0c;具有强氧化性。DDQ在化学合成中具有重要用途&#…

LInux安装nginx方法以及配置文件释义

Linux安装Nginx方法以及所遇见的坑 安装nginx注意细节1、安装所需要的依赖2、下载以及安装nginx3、所有命令执行完毕&#xff0c;启动nginx4、开通防火墙执行完以上所有命令&#xff0c;nginx安装以及启动步骤完成&#xff0c;满足基础访问&#xff0c;访问地址如下&#xff1a…

21.《C语言》——【位操作符】

&#x1f33b;开场语 亲爱的读者&#xff0c;大家好&#xff01;我是一名正在学习编程的高校生。在这个博客里&#xff0c;我将和大家一起探讨编程技巧、分享实用工具&#xff0c;并交流学习心得。希望通过我的博客&#xff0c;你能学到有用的知识&#xff0c;提高自己的技能&a…

视频怎么制作gif动态图片?GIF制作方法分享

视频怎么制作gif动态图片&#xff1f;视频制作GIF动态图片&#xff0c;不仅保留了视频的生动瞬间&#xff0c;还赋予了图像循环播放的魔力。这一技能不仅让创意表达更加丰富多彩&#xff0c;还极大地提升了视觉传播的效率和趣味性。在快节奏的数字时代&#xff0c;GIF动图以其小…
最新文章