看源码学编程系列之kafka(一)
kafka 由于它自身的高性能发送与消费能力,而受到广大企业的喜欢,所以我们就先看看kafka 一些源码实现如下:
  public void run() {
         int messageNo = 1;
         while (true) {
             String messageStr = "Message_" + messageNo;
             long startTime = System.currentTimeMillis();
             if (isAsync) {
                 producer.send(new ProducerRecord<>(topic,
                     messageNo,
                     messageStr), new DemoCallBack(startTime, messageNo, messageStr));// 异步发送
             } else {
                 try {
                     producer.send(new ProducerRecord<>(topic,
                         messageNo,
                         messageStr)).get();// 同步发送
                     System.out.println("Sent message: (" + messageNo + ", " + messageStr + ")");
                 } catch (InterruptedException | ExecutionException e) {
                     e.printStackTrace();
                 }
             }
             ++messageNo;
         }
     }
这段代码摘抄的是,kafka源码 生产者发送消息demo(kafka.examples.Producer) 里面的一个片段,主要是涉及到两个知识点,一个是异步发送消息,
回调函数的实现,另一个就是同步发送,多线程Future.get 模式的实现。现在分别阐述这两种实现方式。
异步回调方式
其实这种方式主要应用在调用多线程执行某个任务时,不用傻傻等到该线程完成后得到相应的反馈信息。举个例子Client端需要调用Server端来执行某个任务,并且希望Server端执行完成后
主动将相应的结果告诉Client端。这个过程就叫做回调了。如下代码:
 public class Client implements CSCallBack {
     private volatile boolean stopThread = false;
     private Server server;
     public Client(Server server) {
         this.server = server;
     }
     public void sendMsg(final String msg){
         System.out.println("ThreadName="+Thread.currentThread().getName()+" 客户端:发送的消息为:" + msg);
         new Thread(new Runnable() {
             @Override
             public void run() {
                 server.getClientMsg(Client.this,msg);// 核心代码1:将被调用方自己当作参数(client)传递到调用方(Server)
                 while(!stopThread) {// 模拟等待另服务器端代码完成
                     System.out.println("ThreadName="+Thread.currentThread().getName()+"客户端:模拟等待回调完成");
                     try {
                         Thread.sleep(50);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }
         }).start();
         System.out.println("ThreadName="+Thread.currentThread().getName()+" 客户端:异步发送成功");
     }
     @Override
     public void process(String status) {
         stopThread = true;
         System.out.println("ThreadName="+Thread.currentThread().getName()+" 客户端:收到服务端回调状态为:" + status);
     }
 }
 public class Server {
     public void getClientMsg(CSCallBack csCallBack , String msg) {
         // 模拟服务端需要对数据处理
         try {
              new Thread(new Runnable() {
                  @Override
                  public void run() {
                      System.out.println("ThreadName="+Thread.currentThread().getName()+" 服务端:服务端接收到客户端发送的消息为:" + msg);
                      while(true) {
                         int max=10,min=1;
                          int ranNum = (int) (Math.random()*(max-min)+min); 
                          if(ranNum >6) {//  当随机数大于5时认为任务完成
                               System.out.println("ThreadName="+Thread.currentThread().getName()+" 服务端:数据处理成功,返回成功状态 200");
                              String status = "200";
                              csCallBack.process(status);// 核心代码2:调用方(Server)任务处理完成相应的任务后,调用被调用方(Client)的方法告知任务完成
                              break;
                          }
                          try {
                             Thread.sleep(80);
                         } catch (InterruptedException e) {
                             e.printStackTrace();
                         }
                      }
                  }
              }).start();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }
其实核心代码就两个:
client端:被调用方自己当作参数(client)传递到调用方(Server)。
Server端:调用方(Server)任务处理完成相应的任务后,调用被调用方(Client)的方法告知任务完成。
同步发送多线程 Future.get 模式实现
这种方式方式主要是用来等待某一项任务完成后,接着顺序执行某项任务。和上面的例子一样都是client 端 向server 端请求完成某项任务,并且期望server 端在完成任务后,返回结果
实例代码如下:
 public class FutureDemo {
     protected RealData realdata = null;
     protected boolean isReady = false;
     public synchronized void requestData(RealData realdata) {// client请求server完成某项任务
         if (isReady) {
             return;
         }
         this.realdata = realdata;
         isReady = true;
         notifyAll();//核心代码2:当请求的任务处理完成时,唤醒等待中的线程
     }
     public synchronized String getResult() {// client等待server完成任务后返回,此处就相当于 Future.get
         while (!isReady) {
             try {
                 wait();//核心代码1:发出请求后等待线程被激活
             } catch (InterruptedException e) {
             }
         }
         return realdata.result;
     }
 }
核心实现代码其实就是多线程里面的,wait 和 notify 实现方式。异步回调 和 同步 Future get 模式最大的区别,举个例子吧,
老婆(client 端)很爱老公,老公(服务器端)每天完成加班很晚,老婆都会等到老公回家然后给他做夜宵(同步 Future get 模式)
老婆(client 端)很爱老公,老公(服务器端)每天完成加班很晚,老婆觉得一直等太累了,就先睡觉,等老公回来后通知老婆(回调),然后老婆再给老公做夜宵(异步回调方式)。
所以大家都期望自己的老婆是, Future get 模式 还是 异步回调模式?
看源码学编程系列之kafka(一)的更多相关文章
- Android 看源码学 Binder
		参考:https://jekton.github.io/2018/04/07/binder-why-RemoteListenerCallback-works/ 参考:https://jekton.gi ... 
- 没必要看源码。。把文档学通就已经牛逼了(我们大多还是在应用层,还达不到研究的程度。附class与examples大全链接)
		[学霸]深圳-鑫 2017/7/11 13:54:07只是学习怎么用QT的话,不用看源码.看帮助文档就很好要学习编码风格与思路,就看看源码 [学神]武汉-朝菌 2017/7/11 13:54:39没必 ... 
- Mybatis源码详解系列(三)--从Mapper接口开始看Mybatis的执行逻辑
		简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ... 
- kafka producer 概要(看源码前,最好能掌握)
		kafakproducer概要(看源码前,最好能理解) 摘要 kafak 被设计用来作为一个统一的平台来处理庞大的数据的实时工具,在设计上有诸多变态的要求 它必须具有高吞吐量才能支持大量事件流 ... 
- [从源码学设计]蚂蚁金服SOFARegistry之程序基本架构
		[从源码学设计]蚂蚁金服SOFARegistry之程序基本架构 0x00 摘要 之前我们通过三篇文章初步分析了 MetaServer 的基本架构,MetaServer 这三篇文章为我们接下来的工作做了 ... 
- [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作
		[从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 目录 [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 0x00 摘要 0x01 业务领域 1.1 SOFARegis ... 
- [从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用
		[从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用 目录 [从源码学设计]蚂蚁金服SOFARegistry之时间轮的使用 0x00 摘要 0x01 业务领域 1.1 应用场景 0x02 定 ... 
- 30s源码刨析系列之函数篇
		前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ... 
- [从源码学设计]蚂蚁金服SOFARegistry之消息总线
		[从源码学设计]蚂蚁金服SOFARegistry之消息总线 目录 [从源码学设计]蚂蚁金服SOFARegistry之消息总线 0x00 摘要 0x01 相关概念 1.1 事件驱动模型 1.1.1 概念 ... 
随机推荐
- asp.net core 设置默认文档index.html
			参考:https://jingyan.baidu.com/article/6079ad0e3e212168fe86db75.html 在Startup.cs的Configure添加 app.UseFi ... 
- mycat+mysql搭建高可用集群1--垂直分库
			mycat垂直分库 本文主要介绍了如何使用mycat对mysql数据库进行垂直分库,包括: 垂直分库的步骤 垂直分库的环境准备 配置mycat垂直分库 1. 垂直分库的步骤 收集分析业务模块间的关系 ... 
- 将JSON反序列化为指定的.NET类型
			前言: 关于将JSON格式数据反序列化为指定的.NET类型数据常见的场景就是,关于网络请求获取请求成功的响应数据.本篇主要讲的的是如何通过使用Newtonsoft.Json中的JsonConvert. ... 
- Vue中Class与Style如何动态绑定
			Class 可以通过对象语法和数组语法进行动态绑定: 对象语法: <div v-bind:class="{ active: isActive, 'text-danger': hasEr ... 
- url中常见符号说明
			如:http://10.1.1.71:9999/auditcenter/api/v1/auditPlanList?pageSize=20&page=1 ?:分隔实际的url和参数 & ... 
- MyBatis 概念
			简介 什么是 MyBatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyB ... 
- 利用SpringBoot+Logback手写一个简单的链路追踪
			目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ... 
- 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取
			1.注册中国大学MOOC 2.选择北京理工大学嵩天老师的<Python网络爬虫与信息提取>MOOC课程 3.学习完成第0周至第4周的课程内容,并完成各周作业 4.提供图片或网站显示的学习进 ... 
- C语言算法动态规划板子题汇总
			本篇博客仅为对动态规划基础问题的状态转移方程进行求解,然后给出对应的注释代码,有关题目的具体内容可在算法导论或网络上进行查看 目录 1.钢管切割(最小值) 2.两条流水线调度 3.多条流水线调度 4. ... 
- ofd电子文档内容分析工具(分析文档、签章和证书)
			前言 ofd是国家文档标准,其对标的文档格式是pdf.ofd文档是容器格式文件,ofd其实就是压缩包.将ofd文件后缀改为.zip,解压后可看到文件包含的内容. ofd文件分析工具下载:点我下载.获取 ... 
