Java 线程池:深入理解与高效应用
在 Java 并发编程中,线程池是一种非常重要的技术。它可以有效地管理和复用线程,提高系统的性能和资源利用率。本文将深入探讨 Java 线程池的概念、原理、使用方法以及最佳实践,帮助读者更好地理解和应用线程池。
一、引言
在现代软件开发中,多线程编程是提高程序性能和响应性的重要手段。然而,直接创建和管理线程会带来一些问题,如线程创建和销毁的开销、资源浪费、线程过多导致的系统性能下降等。为了解决这些问题,Java 提供了线程池技术。线程池可以预先创建一定数量的线程,当有任务需要执行时,从线程池中获取一个空闲线程来执行任务,任务完成后,线程不会被立即销毁,而是返回线程池等待下一个任务。这样可以避免频繁地创建和销毁线程,提高系统的性能和资源利用率。
二、线程池的概念与原理
(一)线程池的基本概念
线程池是一种管理线程的工具,它包含了一组预先创建的线程和一个任务队列。当有任务需要执行时,将任务提交到任务队列中,线程池中的线程会从任务队列中获取任务并执行。如果任务队列中没有任务,线程会进入等待状态,直到有新的任务到来。当线程执行完一个任务后,它会继续从任务队列中获取下一个任务,或者进入等待状态,等待新的任务到来。
(二)线程池的工作原理
- 线程池的创建
- 在创建线程池时,可以指定线程池的核心线程数量、最大线程数量、任务队列的类型和大小等参数。核心线程数量是指线程池中始终保持运行的线程数量,即使这些线程处于空闲状态。最大线程数量是指线程池中允许的最大线程数量,当任务队列已满且核心线程都在忙碌时,线程池会创建新的线程来执行任务,直到线程数量达到最大线程数量。
- 任务的提交
- 当有任务需要执行时,可以通过线程池的
execute
方法或submit
方法将任务提交到线程池中。execute
方法用于提交一个Runnable
任务,没有返回值;submit
方法用于提交一个Callable
任务,有返回值。提交任务后,线程池会根据当前的线程状态和任务队列的情况来决定如何执行任务。
- 当有任务需要执行时,可以通过线程池的
- 线程的执行
- 线程池中的线程会从任务队列中获取任务并执行。如果任务队列中没有任务,线程会进入等待状态,直到有新的任务到来。当线程执行完一个任务后,它会继续从任务队列中获取下一个任务,或者进入等待状态,等待新的任务到来。如果线程在执行任务过程中发生异常,线程池会创建一个新的线程来替代它,并继续执行任务。
- 线程池的关闭
- 当不再需要线程池时,可以通过线程池的
shutdown
方法或shutdownNow
方法来关闭线程池。shutdown
方法会等待线程池中所有的任务执行完毕后再关闭线程池;shutdownNow
方法会立即停止线程池的执行,并尝试中断正在执行任务的线程,返回尚未执行的任务列表。
- 当不再需要线程池时,可以通过线程池的
三、Java 线程池的类型与创建
(一)Java 中的线程池类型
FixedThreadPool
(固定大小线程池)FixedThreadPool
是一种固定大小的线程池,它在创建时指定了线程池的核心线程数量和最大线程数量,并且这两个数量是相等的。当有任务提交到线程池中时,如果线程池中存在空闲线程,就会立即执行任务;如果线程池中没有空闲线程,就会将任务加入到任务队列中等待执行。- 特点:线程数量固定,不会因为任务的增加而创建新的线程,也不会因为任务的减少而销毁线程。适用于需要限制线程数量的场景,如服务器端的连接处理。
CachedThreadPool
(可缓存线程池)CachedThreadPool
是一种可缓存的线程池,它在创建时没有指定线程池的核心线程数量和最大线程数量。当有任务提交到线程池中时,如果线程池中存在空闲线程,就会立即执行任务;如果线程池中没有空闲线程,就会创建一个新的线程来执行任务。当线程在一段时间内没有执行任务时,就会被回收。- 特点:线程数量不固定,可以根据任务的数量自动调整线程数量。适用于执行大量短期任务的场景,如网页爬虫。
ScheduledThreadPool
(定时任务线程池)ScheduledThreadPool
是一种用于执行定时任务的线程池,它在创建时指定了线程池的核心线程数量。当有定时任务提交到线程池中时,线程池会创建一个新的线程来执行任务,并在任务执行完毕后将线程回收。如果在任务执行过程中发生异常,线程池会创建一个新的线程来替代它,并继续执行任务。- 特点:可以执行定时任务和周期性任务。适用于需要定期执行任务的场景,如定时备份数据。
SingleThreadExecutor
(单线程线程池)SingleThreadExecutor
是一种单线程的线程池,它在创建时只有一个核心线程。当有任务提交到线程池中时,这个核心线程会执行任务。如果任务在执行过程中发生异常,线程池会创建一个新的线程来替代它,并继续执行任务。- 特点:只有一个线程在执行任务,保证任务按照提交的顺序依次执行。适用于需要保证任务顺序执行的场景,如日志记录。
(二)创建线程池的方法
- 使用
Executors
工厂类创建线程池- Java 提供了
Executors
工厂类来方便地创建不同类型的线程池。可以使用Executors.newFixedThreadPool
、Executors.newCachedThreadPool
、Executors.newScheduledThreadPool
和Executors.newSingleThreadExecutor
方法分别创建固定大小线程池、可缓存线程池、定时任务线程池和单线程线程池。 - 示例代码:
- Java 提供了
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {// 创建固定大小线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);// 创建可缓存线程池ExecutorService cachedThreadPool = Executors.newCachedThreadPool();// 创建定时任务线程池ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);// 创建单线程线程池ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();}
}
- 使用
ThreadPoolExecutor
构造函数创建线程池- 除了使用
Executors
工厂类创建线程池外,还可以直接使用ThreadPoolExecutor
构造函数来创建线程池。这样可以更加灵活地控制线程池的参数,如核心线程数量、最大线程数量、任务队列的类型和大小等。 - 示例代码:
- 除了使用
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class CustomThreadPoolExample {public static void main(String[] args) {// 创建线程池,核心线程数量为 3,最大线程数量为 5,任务队列大小为 10,任务超时时间为 1 分钟ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3,5,1,TimeUnit.MINUTES,new ArrayBlockingQueue<>(10));}
}
四、线程池的任务提交与执行
(一)提交任务的方法
execute
方法execute
方法用于提交一个Runnable
任务到线程池中执行,没有返回值。如果线程池中的线程数量小于核心线程数量,就会创建一个新的线程来执行任务;如果线程池中的线程数量等于核心线程数量,就会将任务加入到任务队列中等待执行。- 示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecuteExample {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);executorService.execute(() -> {System.out.println("Task executed by thread: " + Thread.currentThread().getName());});executorService.shutdown();}
}
submit
方法submit
方法用于提交一个Callable
任务到线程池中执行,有返回值。如果线程池中的线程数量小于核心线程数量,就会创建一个新的线程来执行任务;如果线程池中的线程数量等于核心线程数量,就会将任务加入到任务队列中等待执行。当任务执行完毕后,会返回一个Future
对象,可以通过这个对象来获取任务的执行结果。- 示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class SubmitExample {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(3);Future<Integer> future = executorService.submit(() -> {System.out.println("Task executed by thread: " + Thread.currentThread().getName());return 42;});try {Integer result = future.get();System.out.println("Task result: " + result);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}executorService.shutdown();}
}
(二)任务的执行过程
- 线程从任务队列中获取任务
- 线程池中的线程会不断地从任务队列中获取任务并执行。如果任务队列中没有任务,线程会进入等待状态,直到有新的任务到来。当有任务提交到线程池中时,线程池会根据当前的线程状态和任务队列的情况来决定如何执行任务。
- 任务的执行
- 线程获取到任务后,会执行任务中的代码。如果任务在执行过程中发生异常,线程池会创建一个新的线程来替代它,并继续执行任务。如果任务执行成功,线程会继续从任务队列中获取下一个任务,或者进入等待状态,等待新的任务到来。
- 任务的返回结果
- 如果提交的任务是一个
Callable
任务,并且使用了submit
方法提交任务,那么可以通过Future
对象来获取任务的返回结果。如果任务在执行过程中发生异常,Future
对象的get
方法会抛出相应的异常。
- 如果提交的任务是一个
五、线程池的参数调整与性能优化
(一)线程池参数的含义与调整方法
- 核心线程数量(corePoolSize)
- 核心线程数量是指线程池中始终保持运行的线程数量,即使这些线程处于空闲状态。当有任务提交到线程池中时,如果线程池中存在空闲线程,就会立即执行任务;如果线程池中没有空闲线程,就会将任务加入到任务队列中等待执行。如果任务队列已满且核心线程都在忙碌时,线程池会创建新的线程来执行任务,直到线程数量达到最大线程数量。
- 调整方法:根据任务的类型和数量来调整核心线程数量。如果任务是 CPU 密集型的,即任务主要消耗 CPU 资源,可以将核心线程数量设置为与 CPU 核心数量相等或稍大一些,以充分利用 CPU 资源。如果任务是 I/O 密集型的,即任务主要消耗 I/O 资源,可以将核心线程数量设置得较大一些,以提高线程的并发度。
- 最大线程数量(maximumPoolSize)
- 最大线程数量是指线程池中允许的最大线程数量。当任务队列已满且核心线程都在忙碌时,线程池会创建新的线程来执行任务,直到线程数量达到最大线程数量。如果任务队列已满且线程数量达到最大线程数量,那么新提交的任务将被拒绝执行。
- 调整方法:根据系统的资源情况和任务的类型来调整最大线程数量。如果系统的资源比较充足,可以将最大线程数量设置得较大一些,以提高线程的并发度。如果系统的资源比较紧张,可以将最大线程数量设置得较小一些,以避免系统资源的过度消耗。
- 任务队列(workQueue)
- 任务队列是用于存储等待执行的任务的队列。当有任务提交到线程池中时,如果线程池中存在空闲线程,就会立即执行任务;如果线程池中没有空闲线程,就会将任务加入到任务队列中等待执行。
- 调整方法:根据任务的类型和数量来选择合适的任务队列类型和大小。如果任务是 CPU 密集型的,可以选择一个较小的任务队列,以避免任务在队列中等待时间过长。如果任务是 I/O 密集型的,可以选择一个较大的任务队列,以提高线程的并发度。常见的任务队列类型有
ArrayBlockingQueue
、LinkedBlockingQueue
、SynchronousQueue
等。
- 线程空闲时间(keepAliveTime)
- 线程空闲时间是指线程在没有任务可执行时的最大等待时间。当线程在一段时间内没有执行任务时,就会被回收。如果线程空闲时间设置得过长,可能会导致线程资源的浪费;如果线程空闲时间设置得过短,可能会导致线程频繁地创建和销毁,增加系统的开销。
- 调整方法:根据任务的类型和数量来调整线程空闲时间。如果任务是短期任务,可以将线程空闲时间设置得较短一些,以避免线程资源的浪费。如果任务是长期任务,可以将线程空闲时间设置得较长一些,以减少线程的创建和销毁次数。
- 拒绝策略(rejectedExecutionHandler)
- 拒绝策略是指当任务队列已满且线程数量达到最大线程数量时,新提交的任务将被拒绝执行时采取的策略。Java 提供了四种拒绝策略,分别是
AbortPolicy
、CallerRunsPolicy
、DiscardOldestPolicy
和DiscardPolicy
。 - 调整方法:根据系统的需求和任务的重要性来选择合适的拒绝策略。如果任务比较重要,可以选择
CallerRunsPolicy
,让提交任务的线程自己执行任务;如果任务不太重要,可以选择DiscardPolicy
或DiscardOldestPolicy
,直接丢弃新提交的任务。
- 拒绝策略是指当任务队列已满且线程数量达到最大线程数量时,新提交的任务将被拒绝执行时采取的策略。Java 提供了四种拒绝策略,分别是
(二)性能优化的技巧与注意事项
- 合理设置线程池参数
- 根据任务的类型和数量来合理设置线程池的参数,如核心线程数量、最大线程数量、任务队列的类型和大小等。避免设置过大或过小的参数,以免影响系统的性能和资源利用率。
- 避免任务阻塞
- 在任务执行过程中,尽量避免任务的阻塞,如 I/O 操作、数据库访问等。可以使用异步 I/O、连接池等技术来减少任务的阻塞时间,提高线程的并发度。
- 监控线程池状态
- 可以使用 Java 的监控工具,如
jconsole
、VisualVM
等,来监控线程池的状态,如线程数量、任务队列大小、任务执行时间等。根据监控结果来调整线程池的参数,以提高系统的性能和资源利用率。
- 可以使用 Java 的监控工具,如
- 避免线程泄漏
- 在任务执行过程中,要注意避免线程泄漏。线程泄漏是指线程在执行任务过程中,由于某些原因没有正确地释放资源,导致线程一直处于运行状态,无法被回收。可以使用
try-with-resources
语句、finally
块等方式来确保资源的正确释放。
- 在任务执行过程中,要注意避免线程泄漏。线程泄漏是指线程在执行任务过程中,由于某些原因没有正确地释放资源,导致线程一直处于运行状态,无法被回收。可以使用
- 考虑任务的优先级
- 如果任务有不同的优先级,可以考虑使用优先级队列来存储任务,以便高优先级的任务能够优先执行。Java 提供了
PriorityBlockingQueue
类来实现优先级队列。
- 如果任务有不同的优先级,可以考虑使用优先级队列来存储任务,以便高优先级的任务能够优先执行。Java 提供了
六、线程池的应用场景与实际案例
(一)应用场景
- 网络服务器
- 在网络服务器中,需要同时处理多个客户端的连接请求。可以使用线程池来管理连接处理线程,提高服务器的并发处理能力。当有新的连接请求到来时,从线程池中获取一个空闲线程来处理连接,连接处理完毕后,线程返回线程池等待下一个连接请求。
- 数据库连接池
- 在数据库访问中,频繁地创建和销毁数据库连接会带来很大的开销。可以使用线程池来管理数据库连接,提高数据库访问的效率。当有数据库访问请求到来时,从线程池中获取一个数据库连接来执行查询操作,查询完毕后,将数据库连接返回线程池等待下一个查询请求。
- 任务调度
- 在任务调度中,需要定期执行一些任务。可以使用定时任务线程池来管理任务执行线程,提高任务调度的效率。当有定时任务需要执行时,从线程池中获取一个空闲线程来执行任务,任务执行完毕后,线程返回线程池等待下一个定时任务。
- 并行计算
- 在并行计算中,需要同时执行多个计算任务。可以使用线程池来管理计算任务执行线程,提高并行计算的效率。将计算任务分解为多个子任务,提交到线程池中执行,最后将子任务的结果合并得到最终的计算结果。
(二)实际案例
- 网络服务器案例
- 假设我们要开发一个简单的网络服务器,能够同时处理多个客户端的连接请求。可以使用线程池来管理连接处理线程,提高服务器的并发处理能力。
- 示例代码:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class NetworkServerExample {public static void main(String[] args) {try {// 创建服务器套接字,监听端口 8080ServerSocket serverSocket = new ServerSocket(8080);System.out.println("服务器启动,监听端口 8080");// 创建线程池,核心线程数量为 5,最大线程数量为 10ExecutorService executorService = Executors.newFixedThreadPool(5);while (true) {// 等待客户端连接Socket clientSocket = serverSocket.accept();System.out.println("客户端连接:" + clientSocket.getInetAddress());// 将客户端连接处理任务提交到线程池executorService.execute(() -> handleClient(clientSocket));}} catch (IOException e) {e.printStackTrace();}}private static void handleClient(Socket clientSocket) {try {// 读取客户端发送的数据java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(clientSocket.getInputStream()));String request = in.readLine();System.out.println("收到客户端请求:" + request);// 处理请求并发送响应java.io.PrintWriter out = new java.io.PrintWriter(clientSocket.getOutputStream(), true);out.println("HTTP/1.1 200 OK");out.println("Content-Type: text/html");out.println();out.println("<html><body>Hello, World!</body></html>");// 关闭客户端连接clientSocket.close();} catch (IOException e) {e.printStackTrace();}}
}
- 数据库连接池案例
- 在数据库访问中,频繁地创建和销毁数据库连接会带来很大的开销。可以使用线程池来管理数据库连接,提高数据库访问的效率。
- 示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;public class DatabaseConnectionPool {private static final int POOL_SIZE = 10;private BlockingQueue<Connection> connectionQueue;public DatabaseConnectionPool() {try {Class.forName("com.mysql.jdbc.Driver");connectionQueue = new LinkedBlockingQueue<>(POOL_SIZE);for (int i = 0; i < POOL_SIZE; i++) {Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");connectionQueue.add(connection);}} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();}}public Connection getConnection() throws InterruptedException {return connectionQueue.take();}public void releaseConnection(Connection connection) {connectionQueue.add(connection);}
}
- 任务调度案例
- 在任务调度中,需要定期执行一些任务。可以使用定时任务线程池来管理任务执行线程,提高任务调度的效率。
- 示例代码:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class TaskSchedulerExample {public static void main(String[] args) {ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);// 每隔 5 秒执行一次任务scheduler.scheduleAtFixedRate(() -> {System.out.println("执行定时任务:" + System.currentTimeMillis());}, 0, 5, TimeUnit.SECONDS);}
}
- 并行计算案例
- 在并行计算中,需要同时执行多个计算任务。可以使用线程池来管理计算任务执行线程,提高并行计算的效率。
- 示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;public class ParallelComputingExample {public static void main(String[] args) {List<Integer> numbers = new ArrayList<>();for (int i = 0; i < 100; i++) {numbers.add(i);}ExecutorService executorService = Executors.newFixedThreadPool(5);List<Future<Integer>> futures = new ArrayList<>();for (Integer number : numbers) {Callable<Integer> task = () -> {return number * number;};futures.add(executorService.submit(task));}int sum = 0;for (Future<Integer> future : futures) {try {sum += future.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}System.out.println("并行计算结果:" + sum);executorService.shutdown();}
}
七、结论
Java 线程池是一种非常强大的并发编程工具,它可以有效地管理和复用线程,提高系统的性能和资源利用率。在实际应用中,我们可以根据任务的类型和数量来选择合适的线程池类型,并合理调整线程池的参数,以达到最佳的性能效果。同时,我们还需要注意避免线程泄漏、任务阻塞等问题,确保线程池的稳定运行。通过合理地使用线程池,我们可以轻松地实现高并发、高性能的 Java 应用程序。
相关文章:
Java 线程池:深入理解与高效应用
在 Java 并发编程中,线程池是一种非常重要的技术。它可以有效地管理和复用线程,提高系统的性能和资源利用率。本文将深入探讨 Java 线程池的概念、原理、使用方法以及最佳实践,帮助读者更好地理解和应用线程池。 一、引言 在现代软件开发中&a…...
week08 zookeeper多种安装与pandas数据变换操作-new
课程1-hadoop-Zookeeper安装 Ububtu18.04安装Zookeeper3.7.1 环境与版本 这里采用的ubuntu18.04环境的基本配置为: hostname 为master 用户名为hadoop 静态IP为 192.168.100.3 网关为 192.168.100.2 防火墙已经关闭 /etc/hosts已经配置全版本下载地址࿱…...
js构造函数和原型对象,ES6中的class,四种继承方式
一、构造函数 1.构造函数是一种特殊的函数,主要用来初始化对象 2.使用场景 常见的{...}语法允许创建一个对象。可以通过构造函数来快速创建多个类似的对象。 const Peppa {name: 佩奇,age: 6,sex: 女}const George {name: 乔治,age: 3,sex: 男}const Mum {nam…...
电脑连接海康相机并在PictureBox和HWindowControl中分别显示。
展示结果: 下面附上界面中所有控件的Name,只需照着红字设置对应的控件Name即可 下面附上小编主界面的全部代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; …...
直播系统源码技术搭建部署流程及配置步骤
系统环境要求 PHP版本:5.6、7.3 Mysql版本:5.6,5.7需要关闭严格模式 Nginx:任何版本 Redis:需要给所有PHP版本安装Redis扩展,不需要设置Redis密码 最好使用面板安装:宝塔面板 - 简单好用的…...
Spring+ActiveMQ
1. 环境搭建 1.1 env-version JDK 1.8 Spring 2.7.13 Maven 3.6 ActiveMQ 5.15.2 1.2 docker-compose.yml version: 3.8services:activemq:image: rmohr/activemq:5.16.3container_name: activemqports:- "61616:61616"- "8161:8161"environment…...
Linux 常用命令总汇
查询所有wifi nmcli dev wifi list 链接wifi sudo nmcli dev wifi connect XXXX password XXXX 查询本机IP ifconfig 查询联网情况 ping www.baidu.com 进入.bash gedit ~/.bashrc sudo dpkg -i XXX.deb 安装超级终端 sudo apt install terminator 超级终端常用…...
fmql之Linux RTC
模拟i2c,连接rtc芯片。 dts: /{ // 根节点i2c_gpio: i2c-gpio {#address-cells <1>;#size-cells <0>;compatible "i2c-gpio";// MIO56-SDA, MIO55-SCL // 引脚编号gpios <&portc 2 0&portc 1 0 >;i2c-gp…...
Flask-SocketIO 简单示例
用于服务端和客户端通信,服务端主动给客户端发送消息 前提: 确保安装了socket库: pip install flask-socketio python-socketio服务端代码 from flask import Flask from flask_socketio import SocketIO import threading import timeap…...
Vue 3 的组件式开发(2)
1 Vue 3 组件的插槽 插槽(Slot)是Vue组件中的一个重要概念,它允许父组件向子组件中插入HTML结构或其他组件,从而实现内容的自定义和复用。以下是对Vue 3组件插槽的详细讲解: 1.1 插槽的基本概念 插槽可以被视为子组…...
python 爬虫 入门 四、线程,进程,协程
目录 一、进程 特征: 使用: 初始代码 进程改装代码 二、线程 特征: 使用: 三、协程 后续:五、抓取图片、视频 线程和进程大部分人估计都知道,但协程就不一定了。 一、进程 进程是操作系统分配资…...
cloak斗篷伪装下的独立站
随着互联网的不断进步,越来越多的跨境电商卖家开始认识到独立站的重要性,并纷纷建立自己的独立站点。对于那些有志于进入这一领域的卖家来说,独立站是什么呢?独立站是指个人或小型团队自行搭建和运营的网站。 独立站能够帮助跨境…...
【Nas】X-DOC:在Mac OS X 中使用 WOL 命令唤醒局域网内 PVE 主机
【Nas】X-DOC:在Mac OS X 中使用 WOL 命令唤醒局域网内 PVE 主机 1、Mac OS X 端2、PVE 端(Debian Linux) 1、Mac OS X 端 (1)安装 wakeonlan 工具 brew install wakeonlan(2)唤醒 PVE 命令 …...
u盘装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法
我们在u盘安装原版win10 iso镜像时,发现在选择硬盘时提示了“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”,直接导致了无法继续安装下去。出现这种情况要怎么解决呢?下面小编分享u盘安装win10系统提示“windows无法安装到这个磁盘…...
Linux系统之dc计算器工具的基本使用
Linux系统之dc计算器工具的基本使用 一、DC工具介绍二、dc命令的基本用法2.1 dc命令的help帮助信息2.2 dc命令基本用法2.3 dc命令常用操作符 三、dc命令的基本使用3.1dc命令的用法步骤3.2 简单数学计算3.3 通过文件来计算3.4 使用--expression计算3.5 使用dc命令进行高精度计算…...
使用Python计算相对强弱指数(RSI)进阶
使用Python计算相对强弱指数(RSI)进阶 废话不多说,直接上主题:> 代码实现 以下是实现RSI计算的完整代码: # 创建一个DataFramedata {DATE: date_list, # 日期CLOSE: close_px_list, # 收盘价格 }df pd.DataF…...
vue 解决:npm ERR! code ERESOLVE 及 npm ERR! ERESOLVE could not resolve 的方案
1、问题描述: 其一、需求为: 想要安装项目所需依赖,成功运行 vue 项目,想要在浏览器中能成功访问项目地址 其二、问题描述为: 在 package.json 文件打开终端平台,通过执行 npm install 命令,…...
Android 原生开发与Harmony原生开发浅析
Android系统 基于Linux ,架构如下 底层 (Linux )> Native ( C层) > FrameWork层 (SystemService) > 系统应用 (闹钟/日历等) 从Android发版1.0开始到现在15,经历了大大小小的变革 从Android6.0以下是个分水岭,6.0之前权限都是直接卸载Manifest中配置 6.0开始 则分普…...
VIVO售后真好:屏幕绿线,4年免费换屏
只要亮屏就有。这也太影响使用了。 本来想换趁机换手机,看了VIVO发布的X200,决定等明年的X200 ULTRA。手头这个就准备修。 查了一下价格,换屏1600,优惠1100。咸鱼上X70 PRO也就800。能不能简单维修就解决呢?于是联系…...
数据类型【MySQL】
文章目录 建立表查看表删除表数据类型floatcharvarcharchar&&varchar 时间日期类型enum和setenum和set查找 建立表 mysql> create table if not exists user1(-> id int ,-> name varchar (20) comment 用户名 ,-> password char (32) comment 用户名的…...
流媒体协议.之(RTP,RTCP,RTSP,RTMP,HTTP)(二)
继续上篇介绍,本篇介绍一下封装RTP的数据格式,如何将摄像头采集的码流,音频的码流,封装到rtp里,传输。 有自己私有协议例子,有rtp协议,参考代码。注意不是rtsp协议。 一、私有协议 玩过tcp协议…...
在 Kakarot ZkEVM 上使用 Starknet Scaffold 构建应用
Starknet 和 EVM 我们所知的智能合约世界一直围绕着以太坊虚拟机(EVM),其主要语言是 Solidity。 尽管 Starknet 通过 STARKs 为以太坊开辟了新的可能性,但其缺点是它有一个不同的虚拟机 (CairoVM),这要求开发者学习 …...
DBeave如何连接达梦数据库,设置达梦驱动,真酷
前言 我们在使用DBeaver连接数据库时,默认可以连接常用的数据库,如mysql数据库,postgresql数据库,oracle数据库。但是,我们的国产数据库达梦数据库,默认在IDEA里面没有驱动,所以还得配置一下才…...
2024年全球 MoonBit 编程创新赛-零基础早鸟教程-使用wasm4八小时开发井子棋小游戏
前言 本篇文章主要分享 “2024年全球 MoonBit 编程创新赛 游戏赛道”参赛过程中九宫棋游戏的开发技巧和心得。以此抛砖引玉。首先介绍下 MoonBit。 月兔语言 MoonBit 是一个用于云计算和边缘计算的 WebAssembly 端到端的编程语言工具链。 您可以访问 https://try.moonbitlang.…...
机器学习4
第3章 线性模型 3.1 线性模型的基本形式 3.1.1 线性模型的核心公式 线性模型通过属性的线性组合进行预测,其核心公式为: [ f(x) \omega_1 X_1 \omega_2 X_2 … \omega_d X_d b ] 其中: ω 1 , ω 2 , . . . , ω d \omega_1, \omega_…...
Python数值计算(33)——simpson 3/8积分公式
1. 背景知识 既然前的Simpson可以通过使用三个点构造二次曲线近似积分,那么,如果点数增加到了4个,然后不就可以构造三次多项式的曲线,实现对目标值的积分吗? 如果采用和上一节介绍的同样的方法,我们可以推…...
<项目代码>YOLOv8路面垃圾识别<目标检测>
YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…...
Java中的注解(白金版)
Spring中常用注解 Springboot中@Validated注解的使用 Swagger中常用注解 @Validate...
actor模型
Actor模型(Actor Model)是一种用于并发计算的数学模型和编程概念,它最早由计算机科学家 Carl Hewitt 等人提出,用于简化对多线程或并发系统的设计和实现。Actor模型在并发编程、分布式系统、消息传递系统等领域具有广泛应用。 核…...
合约门合同全生命周期管理系统:企业智能合同管理的新时代
合约门合同全生命周期管理系统:企业智能合同管理的新时代 1. 引言 随着现代企业的快速发展,合同管理的复杂性日益增加。无论是采购合同、销售合同还是合作协议,合同管理已成为企业运营中至关重要的一环。传统的手工合同管理方式往往效率低下…...
seo 网站关键词优化/诊断网站seo现状的方法
无缘参加去年在广州的UCD年会,这个周末还是想方法去杭州参加了UCD2010年会,收益良多,如果真要细细写下来,恐怕足够写成一本厚厚的垃圾书,只好视自己的心情想到什么就写什么吧。 虽然一直对网络营销抱有浓厚的兴趣&a…...
好的网站建设公司哪家好/360网站推广客服电话
达尔文的进化论是科学史上最大的谎言,在这个谎言的影响下,人类归根于动物,抛弃了道德的约束,失控地发展着私欲,造就了误入歧途的历史。下面转贴一文,剥去历史上最伪的伪科学的画皮,讨伐达尔文的…...
个人网站建设 免费/google seo怎么优化
在函数调用的执行代码中我们会看到这样一些强制转换:EX(function_state).function (zend_function *) op_array;或者:EG(active_op_array) (zend_op_array *) EX(function_state).function;这些不同结构间的强制转换是如何进行的呢?首先我们…...
wordpress手机版网页/网络营销都具有哪些功能
颜色、样式和阴影 fillStyle 设置或返回用于填充绘画的颜色、渐变或模式 strokeStyle 设置或返回用于笔触的颜色、渐变或模式 shadowColor 设置或返回用于阴影的颜色 shadowBlur 设置或返回用于阴影的模糊级别 shadowOffsetX 设置或返回阴影距形状的水平距离 shadowOffse…...
一级a做爰网站中国/如何注册域名网站
把数据库从oracle迁移到PPASPPAS有两个迁移工具,一个图形界面的,一个命令行的,下面以图形界面为例。1首先需要在目标数据库系统PPAS上建立和源库对应的用户和对等的权限,再建立目标数据库。create user " USERNAMEXXX "…...
用vs2012做网站案例/电商网络销售是做什么
递归遍历|非递归遍历前言一、对称二叉树二、递归与迭代1、递归回溯2、栈与迭代总结参考文献前言 二叉树的结构为root,左子树,右子树,左右子树也同时具备root,左子树和右子树,所以二叉树是一个典型的递归结构。保持递归…...