Java线程中:Runnable和Callable的区别和联系

news2024/11/29 0:45:50

点个关注,必回关

文章目录

  • 一、Java提供了三种创建线程的方法
    • 1.继承Thread
    • 2.实现Runnable接口
    • 3.通过Callable和Future创建线程
  • 二、Runnable和Callable的区别和联系
    • 1.定义接口
      • (1) Runnable
      • (2)Callable
      • (3)Future
      • (4)FutureTask
    • 2.相同点
    • 3.不同点
    • 4.示例
      • (1)示例一
      • (2) 运行结果:
      • (3)示例二
      • (4) 运行结果:
      • (5)示例三
      • (6) 运行结果:
    • 5.关系图
    • 图一:
    • 图二:

一、Java提供了三种创建线程的方法

1.继承Thread

 1 public class Thread2Thread {
 2     public static void main(String[] args) {
 3         new MyThread1().start();
 4         new Thread(new MyThread1(), "线程2").start();
 5     }
 6 }
 7 
 8 /**
 9  * 通过继承Thread类
10  */
11 class MyThread1 extends Thread {
12     /**
13      * 重写run方法
14      */
15     @Override
16     public void run() {
17         // TODO Auto-generated method stub
18         super.run();
19     }
20 }

2.实现Runnable接口

 1 package com.testthread.demo4;
 2 
 3 import java.util.concurrent.ExecutorService;
 4 
 5 import static java.util.concurrent.Executors.*;
 6 
 7 public class Thread2Runnable {
 8 
 9     public static void main(String[] args) {
10 
11         //case1:通过实现Runnable接口,来实现run方法的具体逻辑
12         new Thread(new MyThread2(), "线程1").start();
13         //case2:匿名内部类
14         new Thread(new Runnable() {
15             @Override
16             public void run() {
17                 // TODO Auto-generated method stub
18 
19             }
20         }, "线程2").start();
21 
22         //其实case1和case2的本质是一样的
23         
24         //case3:作为线程任务提交给线程池,通过线程池维护的工作者线程来执行。
25         ExecutorService executor = newCachedThreadPool();
26         MyThread2 myThread2 = new MyThread2();
27         executor.execute(myThread2);
28         executor.shutdown();
29     }
30 }
31 
32 /**
33  * 实现Runnable接口的线程类
34  */
35 class MyThread2 implements Runnable {
36 
37     /**
38      * 重写run方法
39      */
40     @Override
41     public void run() {
42         // TODO Auto-generated method stub
43     }
44 }

3.通过Callable和Future创建线程

 1 import java.util.concurrent.Callable;
 2 import java.util.concurrent.FutureTask;
 3 
 4 public class Thread2Callable {
 5     public static void main(String[] args) {
 6         //创建 Callable 实现类的实例
 7         MyCallable myCallable = new MyCallable();
 8         //使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值
 9         FutureTask<String> futureTask = new FutureTask<String>(myCallable);
10         String res = null;
11         try {
12             //使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程
13             //没这句,下句代码获取不到结果,会一直等待执行结果
14             new Thread(futureTask,"线程1").start();
15             //调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值
16             res = futureTask.get();
17         } catch (Exception e) {
18             e.printStackTrace();
19         }
20         System.out.println(res);
21     }
22 }
23 /**
24  * 创建 Callable 接口的实现类,并实现 call() 方法
25  */
26 class MyCallable implements Callable<String> {
27 
28     /**
29      * 该 call() 方法将作为线程执行体,并且有返回值
30      */
31     @Override
32     public String call() throws Exception {
33         return "success";
34     }
35 }

二、Runnable和Callable的区别和联系

1.定义接口

(1) Runnable

其中Runnable应该是我们最熟悉的接口,它只有一个run()函数,用于将耗时操作写在其中,该函数没有返回值。然后使用某个线程去执行该runnable即可实现多线程,Thread类在调用start()函数后就是执行的是Runnable的run()函数。

Runnable的声明如下 :

1 public interface Runnable {
2     /*
3      * @see     java.lang.Thread#run()
4      */
5     public abstract void run();
6 }

(2)Callable

Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。

Callable的声明如下 :

1 public interface Callable<V> {
2     /**
3      * Computes a result, or throws an exception if unable to do so.
4      *
5      * @return computed result
6      * @throws Exception if unable to compute a result
7      */
8     V call() throws Exception;
9 }

(3)Future

Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果(Future简介)。

Future声明如下 :

 1 public interface Future<V> {
 2  
 3     /**
 4      * Attempts to cancel execution of this task.  This attempt will
 5      * fail if the task has already completed, has already been cancelled,
 6      * or could not be cancelled for some other reason. If successful,
 7      * and this task has not started when <tt>cancel</tt> is called,
 8      * this task should never run.  If the task has already started,
 9      * then the <tt>mayInterruptIfRunning</tt> parameter determines
10      * whether the thread executing this task should be interrupted in
11      * an attempt to stop the task.
12      */
13     boolean cancel(boolean mayInterruptIfRunning);
14  
15     /**
16      * Returns <tt>true</tt> if this task was cancelled before it completed
17      * normally.
18      */
19     boolean isCancelled();
20  
21     /**
22      * Returns <tt>true</tt> if this task completed.
23      *
24      */
25     boolean isDone();
26  
27     /**
28      * Waits if necessary for the computation to complete, and then
29      * retrieves its result.
30      *
31      * @return the computed result
32      */
33     V get() throws InterruptedException, ExecutionException;
34  
35     /**
36      * Waits if necessary for at most the given time for the computation
37      * to complete, and then retrieves its result, if available.
38      *
39      * @param timeout the maximum time to wait
40      * @param unit the time unit of the timeout argument
41      * @return the computed result
42      */
43     V get(long timeout, TimeUnit unit)
44         throws InterruptedException, ExecutionException, TimeoutException;
45 }

(4)FutureTask

FutureTask是一个RunnableFuture

1 public class FutureTask<V> implements RunnableFuture<V>

RunnableFuture实现了Runnbale又实现了Futrue这两个接口

1 public interface RunnableFuture<V> extends Runnable, Future<V> {
2     /**
3      * Sets this Future to the result of its computation
4      * unless it has been cancelled.
5      */
6     void run();
7 }

另外FutureTaslk还可以包装Runnable和Callable, 由构造函数注入依赖。

1     public FutureTask(Callable<V> callable) {
 2         if (callable == null)
 3             throw new NullPointerException();
 4         this.callable = callable;
 5         this.state = NEW;       // ensure visibility of callable
 6     }
 7  
 8     public FutureTask(Runnable runnable, V result) {
 9         this.callable = Executors.callable(runnable, result);
10         this.state = NEW;       // ensure visibility of callable
11     }

上面代码块可以看出:Runnable注入会被Executors.callable()函数转换为Callable类型,即FutureTask最终都是执行Callable类型的任务。

该适配函数的实现如下 :

1     public static <T> Callable<T> callable(Runnable task, T result) {
2         if (task == null)
3             throw new NullPointerException();
4         return new RunnableAdapter<T>(task, result);
5     }

RunnableAdapter适配器

 1     /**
 2      * A callable that runs given task and returns given result
 3      */
 4     static final class RunnableAdapter<T> implements Callable<T> {
 5         final Runnable task;
 6         final T result;
 7         RunnableAdapter(Runnable task, T result) {
 8             this.task = task;
 9             this.result = result;
10         }
11         public T call() {
12             task.run();
13             return result;
14         }
15     }

FutureTask实现Runnable,所以能通过Thread包装执行,

FutureTask实现Runnable,所以能通过提交给ExcecuteService来执行

注:ExecuteService:创建线程池实例对象,其中有submit(Runnable)、submit(Callable)方法

ExecturService:https://blog.csdn.net/suifeng3051/article/details/49443835

还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。

因此FutureTask是Future也是Runnable,又是包装了的Callable( 如果是Runnable最终也会被转换为Callable )。

2.相同点

1 都是接口
2 都可以编写多线程程序
3 都采用Thread.start()启动线程

3.不同点

1 Callable规定的方法是call(),而Runnable规定的方法是run().
2 Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
3 call()方法可抛出异常,而run()方法是不能抛出异常的。–run()方法异常只能在内部消化,不能往上继续抛
4 运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。
5 它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
6 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
7 Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
注:Callalbe接口支持返回执行结果,需要调用FutureTask.get()得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞

4.示例

(1)示例一

 1 package com.xzf.callable;
 2  
 3 import java.util.concurrent.Callable;
 4 import java.util.concurrent.ExecutorService;
 5 import java.util.concurrent.Executors;
 6 import java.util.concurrent.Future;
 7 import java.util.concurrent.FutureTask;
 8  
 9 public class RunnableFutureTask {
10     static ExecutorService executorService = Executors.newSingleThreadExecutor();    //创建一个单线程执行器
11     public static void main(String[] args) {
12         runnableDemo();    
13         futureDemo();
14     }
15     /**
16      * new Thread(Runnable arg0).start(); 用Thread()方法开启一个新线程
17      * runnable, 无返回值
18      */
19     static void runnableDemo() {
20         new Thread(new Runnable() {                
21             public void run() {
22                 System.out.println("runnable demo:" + fibc(20));    //有值
23             }
24             
25         }).start();
26     }
27     /**
28      * Runnable实现的是void run()方法,无返回值
29      * Callable实现的是 V call()方法,并且可以返回执行结果
30      * Runnable可以提交给Thread,在包装下直接启动一个线程来执行
31      * Callable一般都是提交给ExecuteService来执行
32      */ 
33      
34     static void futureDemo() {
35         try {
36             Future<?> result1 = executorService.submit(new Runnable() {
37                 public void run() {
38                     fibc(20);
39                 }
40             });
41             System.out.println("future result from runnable:"+result1.get());    //run()无返回值所以为空,result1.get()方法会阻塞
42             Future<Integer> result2 = executorService.submit(new Callable<Integer>()     {
43                 public Integer call() throws Exception {
44                     return fibc(20);    
45                 }
46             });
47             System.out.println("future result from callable:"+result2.get());    //call()有返回值,result2.get()方法会阻塞
48             FutureTask<Integer> result3 = new FutureTask<Integer>(new Callable<Integer>() {
49                 public Integer call() throws Exception {
50                     return fibc(20);
51                 }
52             });
53             executorService.submit(result3);    
54             System.out.println("future result from FutureTask:" + result3.get());    //call()有返回值,result3.get()方法会阻塞
55             
56             /*因为FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行*/
57             FutureTask<Integer> result4 = new FutureTask<Integer>(new Runnable() {
58                 public void run() {
59                     fibc(20);
60                 }
61             },fibc(20));    
62             executorService.submit(result4);
63             System.out.println("future result from executeService FutureTask :" + result4.get());    //call()有返回值,result3.get()方法会阻塞
64             //这里解释一下什么FutureTask实现了Runnable结果不为null,这就用到FutureTask对Runnable的包装,所以Runnable注入会被Executors.callable()函数转换成Callable类型
65  
66             FutureTask<Integer> result5 = new FutureTask<Integer>(new Runnable() {
67                 public void run() {
68                     fibc(20);
69                 }
70             },fibc(20));
71             new Thread(result5).start();
72             System.out.println("future result from Thread FutureTask :" + result5.get());    //call()有返回值,result5.get()方法会阻塞
73             
74         } catch (Exception e) {
75             e.printStackTrace();
76         }finally {
77             executorService.shutdown();
78         }
79     }
80     static int fibc(int num) {
81         if (num==0) {
82             return 0;
83         }
84         if (num==1) {
85             return 1;
86         }
87         return fibc(num-1) + fibc(num-2);
88     }
89 }

(2) 运行结果:

1 runnable demo:6765
2 future result from runnable:null
3 future result from callable:6765
4 future result from FutureTask:6765
5 future result from executeService FutureTask :6765
6 future result from Thread FutureTask :6765

(3)示例二

 1 package com.testthread.test;
 2 
 3 import java.util.concurrent.*;
 4 import java.util.Date;
 5 import java.util.List;
 6 import java.util.ArrayList;
 7 
 8 public class Test implements Callable<Object> {
 9     private String taskNum;
10 
11     Test(String taskNum) {
12         this.taskNum = taskNum;
13     }
14 
15     public static void main(String[] args) {
16         System.out.println("----程序开始运行----");
17         Date date1 = new Date();
18         int taskSize = 5; // 创建一个线程池
19         ExecutorService pool = Executors.newFixedThreadPool(taskSize); // 创建多个有返回值的任务
20         List<Future> list = new ArrayList<Future>();
21         try {
22             for (int i = 0; i < taskSize; i++) {
23                 Callable c = new Test(i + " "); // 执行任务并获取Future对象
24                 Future f = pool.submit(c);
25                 list.add(f);
26             }
27             // 获取所有并发任务的运行结果
28             for (Future f : list) {
29                 // 从Future对象上获取任务的返回值,并输出到控制台
30                 System.out.println(">>>" + f.get().toString());
31             }
32         } catch (InterruptedException e) {
33             e.printStackTrace();
34         } catch (ExecutionException e) {
35             e.printStackTrace();
36         } finally {// 关闭线程池
37             pool.shutdown();
38         }
39         Date date2 = new Date();
40         System.out.println("----程序结束运行----,程序运行时间【" + (date2.getTime() - date1.getTime()) + "毫秒】");
41     }
42 
43     @Override
44     public Object call() throws Exception {
45         System.out.println(">>>" + taskNum + "任务启动");
46         Date dateTmp1 = new Date();
47         Thread.sleep(1000);
48         Date dateTmp2 = new Date();
49         long time = dateTmp2.getTime() - dateTmp1.getTime();
50         System.out.println(">>>" + taskNum + "任务终止");
51         return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
52     }
53 }

(4) 运行结果:

 1 ----程序开始运行----
 2 >>>1 任务启动
 3 >>>0 任务启动
 4 >>>3 任务启动
 5 >>>2 任务启动
 6 >>>4 任务启动
 7 >>>1 任务终止
 8 >>>3 任务终止
 9 >>>0 任务终止
10 >>>0 任务返回运行结果,当前任务时间【1029毫秒】
11 >>>2 任务终止
12 >>>1 任务返回运行结果,当前任务时间【1029毫秒】
13 >>>2 任务返回运行结果,当前任务时间【1030毫秒】
14 >>>3 任务返回运行结果,当前任务时间【1030毫秒】
15 >>>4 任务终止
16 >>>4 任务返回运行结果,当前任务时间【1030毫秒】
17 ----程序结束运行----,程序运行时间【1146毫秒】

(5)示例三

 1 package com.testthread.test;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 import java.util.Map;
 7 import java.util.concurrent.Callable;
 8 import java.util.concurrent.ExecutionException;
 9 import java.util.concurrent.ExecutorService;
10 import java.util.concurrent.FutureTask;
11 
12 import static java.util.concurrent.Executors.newFixedThreadPool;
13 
14 public class Test2 {
15 
16     public static void main(String[] args) {
17         Map<String, Object> resultMap = new HashMap<>();
18         int count = 10;
19         ExecutorService executorService = newFixedThreadPool(10);
20         long start = System.currentTimeMillis();
21         try {
22             List<FutureTask> list = new ArrayList();
23             for (int i = 0; i < count; i++) {
24                 FutureTask<Map<String, Object>> result = new FutureTask<Map<String, Object>>(myCall(i + ""));
25                 executorService.submit(result);
26                 list.add(result);
27             }
28             for (int i = 0; i < count; i++) {
29                 Map<String, Object> resultMapShow = (Map<String, Object>) list.get(i).get();
30                 System.out.println("resultMapShow = " + resultMapShow);
31                 Map<String, Object> body = (Map<String, Object>) resultMapShow.get("body");
32                 resultMap.put("aa" + i, body.get("aa"));
33             }
34             System.out.println("====>took:" + (System.currentTimeMillis() - start));
35 
36         } catch (InterruptedException e) {
37             e.printStackTrace();
38         } catch (ExecutionException e) {
39             e.printStackTrace();
40         } finally {
41             executorService.shutdown();
42         }
43         System.out.println("resultMap = " + resultMap);
44         System.out.println("==>took:" + (System.currentTimeMillis() - start));
45     }
46 
47 
48     public static Callable<Map<String, Object>> myCall(String taskId) {
49         Callable<Map<String, Object>> callable = new Callable<Map<String, Object>>() {
50             @Override
51             public Map<String, Object> call() throws Exception {
52                 return queryMethod(taskId);
53             }
54         };
55         return callable;
56     }
57 
58     private static Map<String, Object> queryMethod(String taskId) {
59         try {
60             System.out.println(" ==>任务启动" + taskId);
61             long startI = System.currentTimeMillis();
62             Thread.sleep(500);
63 //            System.out.println("   sleep:500ms");
64             System.out.println(" ==>任务终止" + taskId + " 任务时间:" + (System.currentTimeMillis() - startI));
65         } catch (InterruptedException e) {
66             e.printStackTrace();
67         }
68         Map<String, Object> resultMap = new HashMap<>();
69         Map<String, Object> head = new HashMap<>();
70         head.put("retFlag", "0000");
71         head.put("retMsg", "成功");
72         Map<String, Object> body = new HashMap<>();
73         body.put("aa", "11");
74         resultMap.put("head", head);
75         resultMap.put("body", body);
76         return resultMap;
77     }
78 }

(6) 运行结果:

 1  ==>任务启动0
 2  ==>任务启动1
 3  ==>任务启动2
 4  ==>任务启动3
 5  ==>任务启动4
 6  ==>任务启动5
 7  ==>任务启动6
 8  ==>任务启动7
 9  ==>任务启动8
10  ==>任务启动9
11  ==>任务终止0 任务时间:501
12 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
13  ==>任务终止4 任务时间:502
14  ==>任务终止3 任务时间:502
15  ==>任务终止2 任务时间:502
16  ==>任务终止1 任务时间:502
17 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
18 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
19 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
20 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
21  ==>任务终止6 任务时间:502
22  ==>任务终止5 任务时间:502
23 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
24 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
25  ==>任务终止8 任务时间:501
26  ==>任务终止7 任务时间:501
27 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
28 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
29  ==>任务终止9 任务时间:501
30 resultMapShow = {head={retMsg=成功, retFlag=0000}, body={aa=11}}
31 ====>took:525
32 resultMap = {aa1=11, aa0=11, aa3=11, aa2=11, aa5=11, aa4=11, aa7=11, aa6=11, aa9=11, aa8=11}
33 ==>took:526

5.关系图

图一:

在这里插入图片描述

图二:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

onnx-graphsurgeon----ONNX计算图修改神器

0. 简介 作为深度学习用户&#xff0c;经常会听到ONNX、TensorRT等一系列常用的文件保存格式。而对于ONNX而言&#xff0c;经常我们会发现在利用TensorRT部署到NVIDIA显卡上时&#xff0c;onnx模型的计算图不好修改&#xff0c;在以前的操作中很多时候大佬是将onnx转换成ncnn的…

vscode中安装python运行调试环境

在运行代码之前&#xff0c;需要到微软商店下载安装python环境&#xff0c;35m&#xff0c;都是自动的。 1、安装python 的extensions插件。 ctrlshiftx 输入 python 后点击 install 按钮。 2、新建文件夹spider文件夹。 3、在新建文件夹spider下新建文件spider.py源代码。…

注册OpenAI体验ChatGPT实战演示

什么是ChatGPT ChatGPT&#xff0c;美国OpenAI 研发的聊天机器人程序 &#xff0c;于2022年11月30日发布的人工智能技术驱动的自然语言处理工具&#xff0c;能够真正像人一样完成交流和任务处理。日前&#xff0c;ChatGPT已经更新多个版本&#xff0c;很多大厂也都在接入其API。…

Spark On YARN时指定Python版本

坑很多&#xff0c;直接上兼容性最佳的命令&#xff0c;将python包上传到hdfs或者file:/home/xx/(此处无多余的/) # client 模式 $SPARK_HOME/spark-submit \ --master yarn \ --deploy-mode client \ --num-executors 2 \ --conf "spark.yarn.dist.archives<Python包…

超店有数,tiktok变现 |TikTok最新选品秘籍!让你爆单销量10W+

商家想要自家产品爆单&#xff0c;获得更高的转化&#xff0c;tiktok变现&#xff0c;选品很重要。但很多商家在选品上&#xff0c;找不到头绪。那不妨看看一下的内容&#xff0c;可以帮助你找到选品的思路方向和方法。一、tiktok选品方向1、 考虑垂直细分产品考虑垂直细分领域…

Vue3快速入门【二】

Vue3快速入门一、传值父传子&#xff0c;子传父v-model二、插槽2.1、匿名插槽2.2、具名插槽2.3、插槽作用域2.4、插槽作用域案例2.4.1、初始布局2.4.2、插槽使用2.4.3、点击编辑按钮获取本行数据&#xff08;插槽作用域的使用&#xff09;2.4.4、类型书写优化2.4.5、全局接口抽…

云计算|OpenStack|社区版OpenStack安装部署文档(十一--- 如何获取镜像---Rocky版)

前言&#xff1a; 前面我们使用虚拟机搭建了一个openstack集群&#xff0c;也就是在VM虚拟机的基础上模拟了一个简单的基于openstack社区版Rocky的私有云&#xff0c;但&#xff0c;不管任何部署安装工作&#xff0c;最后其实都是需要有实际的应用的&#xff0c;也就是常说的实…

拿来就用的Java海报生成器ImageCombiner(一)

背景如果您是UI美工大师或者PS大牛&#xff0c;那本文一定不适合你&#xff1b;如果当您需要自己做一张海报时&#xff0c;可以立马有小伙伴帮您实现&#xff0c;那本文大概率也不适合你。但是&#xff0c;如果你跟我一样&#xff0c;遇上到以下场景&#xff0c;最近公司上了不…

新手小白适合做跨境电商吗?

今天的跨境电商已经逐渐成熟&#xff0c;靠运气赚钱的时代早已过去&#xff0c;馅饼不可能从天上掉下来&#xff0c;尤其是你想做一个没有货源的小白劝你醒醒。做跨境电商真的不容易&#xff0c;要想做&#xff0c;首先要分析自己是否适合做。米贸搜整理了以下资料&#xff0c;…

硬件设计—高性能ADC前端电路

高性能模数转换器&#xff08;ADC&#xff09;一般对系统的性能有非常高的要求&#xff0c;而AD芯片的“前端”的输入电路设计对ADC系统的的性能有非常大的影响。以下主要介绍了ADC芯片前端输入使用放大器和变压器各自的优势。 1、放大器和变压器根本区别 放大器是有源器件&am…

Docker进阶 - 8. docker network 网络模式之 container

目录 1. container 模式概述 2. 使用Alpine操作系统来验证 container 模式 1. container 模式概述 container网络模式新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡&#xff0c;配置自己的IP&#xff0c;而是和一个…

ChatGPT注册+微信自动回复

ChatGPT注册微信自动回复1 注册OpenAI1.1 科学上网1.2 准备用于注册OpenAI的邮箱1.3 准备用于验证OpenAI的手机号1.4 注册OpenAI1.5 使用OpenAI2 基于ChatGPT微信实现自动回复2.1 原理2.2 实现ChatGPT是OpenAI基于GPT-3模型构建的自然语言处理模型&#xff0c;近几天ChatGPT突然…

这款浏览器火了,能快速使用ChatGPT,简单一看就会

当下ChatGPT很火&#xff0c;影响的人数非常广泛。作为聊天机器人模型&#xff0c;ChatGPT能完成写论文、编代码、写新闻、画画等高难度要求。那么&#xff0c;如何使用ChatGPT呢&#xff1f;下面介绍一下几个使用方法。值得一提的&#xff0c;目前已经有浏览器支持使用ChatGPT…

C++程序设计——多态:虚函数、抽象类、虚函数表

注&#xff1a;以下示例均是在VS2019环境下 一、多态的概念 通俗来讲&#xff0c;多态就是多种形态&#xff0c;当不同的对象去完成某个行为时&#xff0c;会产生出不同的状态。即不同继承关系的类对象&#xff0c;去调用同一函数时&#xff0c;产生不同的行为。 比如”叫“这…

【React】course

《千锋HTML5实战就业班React课程体系V16版本》课程资料 一、关于React 英文官网&#xff1a;https://reactjs.org/ 中文官网&#xff1a;https://zh-hans.reactjs.org/ React 起源于 Facebook 的内部项目&#xff0c;因为该公司对市场上所有 JavaScript MVC 框架&#xff0c…

JAVA工具篇--1 Idea中 Gradle的使用

前言&#xff1a; 既然我们已经使用Maven 来完成对项目的构建&#xff0c;为什么还要使用Gradle 进行项目的构建&#xff1b;gradle和maven都可以作为java程序的构建工具&#xff0c;但两者还是有很大的不同之处的&#xff1a;1.可扩展性&#xff0c;gradle比较灵活&#xff0c…

RabbitMQ-消息应答

一、介绍为了保证消息在发送过程中不丢失&#xff0c;rabbitmq引入消息应答机制&#xff0c;消息应答就是&#xff1a;消费者在接收到消息并且处理该消息之后&#xff0c;告诉rabbitmq它已经处理了&#xff0c;rabbitmq可以把该消息删除了。二、自动应答消息发送之后立即被认为…

pytest-fixture

fixture是pytest特有的功能&#xff0c;它用pytest.fixture标识&#xff0c;定义在函数前面。在编写测试函数的时候&#xff0c;可以将此函数的名称作为传入参数&#xff0c;pytest会以依赖注入方式将该函数的返回值作为测试函数的传入参数。fixture主要的目的是为了提供一种可…

从C语言向C++过渡

文章目录前言1.命名空间1.域的概念2.命名空间的使用2.C输入&输出3.缺省参数1.概念2.分类3.注意事项4.函数重载5.引用1.概念2.使用注意事项3.引用使用场景4.指针和引用的区别6.内联函数7.auto关键字8.nullptr前言 C被成为带类的C,本文由C语言向C过度&#xff0c;将会初步介…

电子器件系列32:逻辑与门芯片74LS11

一、编码规则 先看看这个代码的意思&#xff1a;74LS11 74是一个系列&#xff08;74 表示为工作温度范围&#xff0c;74: 0 ~ 70度。&#xff09; ls的意思就是工艺类型&#xff08;Bipolar(双极)工艺&#xff09; 11是代码 什么是74系列逻辑芯片&#xff1f; - 知乎 什么是…