1. 因何而写

    网上关于bytebuffer的文章真的很多,为何在此还要写一篇呢?主要是基于以下几点考虑

    1. 很多人在使用t-io时,还不会bytebuffer,只会照着t-io提供的例子照猫画虎,不利于灵活运用
    2. 网上搜到的一些相关文章,讲得不是太易懂,不利于初学者灵活运用bytebuffer
    3. 本文旨在讲解灵活运用bytebuffer所需的最小知识,以帮助用户快速掌握bytebuffer
  2. 用极易的方式认识一下bytebuffer

    1. bytebuffer之第一眼印象

      我们可以把bytebuffer理解成如下几个成员组成的一个新对象,对,就是一个普通的java对象,像string一样的java对象。(强调一下,这里只是说这样理解,实际上有些bytebuffer的实现类并非这样实现,并且这里只列出掌握bytebuffer所需要的最小知识集合,其它诸如mark等字段本文并不介绍,以免增加初学者的惑度

      1. byte[] bytes: 用来存储数据
      2. int capacity: 用来表示bytes的容量,那么可以想像capacity就等于bytes.size(),此值在初始化bytes后,是不可变的。
      3. int limit: 用来表示bytes实际装了多少数据,可以容易想像得到limit <= capacity,此值是可灵活变动的
      4. int position: 用来表示在哪个位置开始往bytes写数据或是读数据,此值是可灵活变动的

      通过下图,对bytebuffer形成一个感观认识吧

    2. bytebuffer之常用操作及各操作对内部变量带来的变化

      1. 创建bytebuffer: ByteBuffer.allocate(6)

      2. 写入一个字节: byteBuffer.put((byte)3)

      3. 读取一个字节: byte bs = byteBuffer.get()

        对于刚刚写好的bytebuffer,我们要读取它的内容,需要先设置一下position和limit,否则读的位置就不对


        byteBuffer.position(0); //设置position到0位置,这样读数据时就从这个位置开始读
        byteBuffer.limit(1); //设置limit为1,表示当前bytebuffer的有效数据长度是1

        我们看一下,设置position和limit后,bytebuffer的内部变化

        接下来,我们就可以读取刚才写入的数据了


        byte bs = byteBuffer.get();

    3. bytebuffer之使用心得

      这里说的是作者本人使用bytebuffer的一些心得,这些与其说是心得,不如说是实践+测试得来的一些经验,所以并不保证就是权威的,欢迎有更深研究的朋友来合理讨论,如果有不同意见,可以以更好的论据来说服对方。

      1. HeapByteBuffer.get(byte[], int, int)效率不如 System.arraycopy()

        前者实现的原理是用for循环来做的,后者是内存复制,t-io一般是用后者来做bytebuffer的组合,譬如SendRunnable.java的下面这段代码


        ByteBuffer allByteBuffer = ByteBuffer.allocate(allBytebufferCapacity);
        byte[] dest = allByteBuffer.array();
        for (ByteBuffer byteBuffer : byteBuffers) {
        if (byteBuffer != null) {
        int length = byteBuffer.limit();
        int position = allByteBuffer.position();
        System.arraycopy(byteBuffer.array(), 0, dest, position, length);
        allByteBuffer.position(position + length);
        }
        }

        注意:如果DirectBuffer并不能用System.arraycopy来代替get(byte[], int, int),因为这货的内部实现不是byte[]的

      2. jdk自带的bytebuffer已经足够好用

        有一些nio/aio框架喜欢自己弄一套bytebuffer来,既增加了作者自己的工作量,又增加了用户的学习成本,但我们要知道一点,nio/aio在发送数据时,最终的参数是jdk的bytebuffer,我们真的有必要再作一次转换和计算吗?尽管某些中间过程是“零拷贝”(这个“零拷贝”也是有额外的计算成本的)的,但是jdk版bytebuffer的诞生到发送完毕,这整个过程经历了哪些操作呢?真的是如某书某博客上所说的“零拷贝”吗?更不应该把某些对象池的做法也牵强附会到“零拷贝”的概念中来----对象池属对象重复利用范畴,既然是重复利用自然便已经默认有零拷贝的属性了,但是对象池本身的维护也是需要消耗资源的,所以并不是所有场景说用了对象池,性能就提升了,有时候用不好反而增加负担,所以万事要以测试数据为准,不应盲目人云亦云!

  3. 最后附上bytebuffer的示例程序

    这里附上bytebuffer的示例程序,用户可以自己debug观察观察,增加bytebuffer的相关概念,以便更灵活的运用bytebuffer


    import java.nio.ByteBuffer; /**
    * @author tanyaowu
    * 2017年5月1日 上午9:00:50
    */
    public class Ts { /**
    *
    * @author: tanyaowu
    */
    public Ts() {
    } /**
    * @param args
    * @author: tanyaowu
    */
    public static void main(String[] args) {
    ByteBuffer byteBuffer = ByteBuffer.allocate(6);
    byteBuffer.put((byte)3); byteBuffer.position(0); //设置position到0位置,这样读数据时就从这个位置开始读
    byteBuffer.limit(1); //设置limit为1,表示当前bytebuffer的有效数据长度是1 byte bs = byteBuffer.get();
    System.out.println(byteBuffer);
    }
    }

图解java中的bytebuffer的更多相关文章

  1. 一、图解Java中String不可变性

    这里有一堆例子来说明Java的String的不可变性. 1.声明一个String String s = "abcd"; s 变量保存string对象的引用,下面的箭头解释成保存了哪 ...

  2. Java中this、static关键字的内存图解

    Java中的关键字有很多,abstract  default  goto*  null  switch  boolean  do  if  package  nchronzed  break  dou ...

  3. Java中数组在内存中的图解

    Java中的数组在内存中的图解,其实对于数组,还是比较熟悉的,平时用的也是很多的,在看数据结构与算法的极客时间专栏,最常用的10个数据结构:数组.链表.栈.队列.散列表.二叉树.堆.跳表.图.Trie ...

  4. (转载)图解Java多态内存分配以及多态中成员方法的特点

    图解Java多态内存分配以及多态中成员方法的特点   图解Java多态内存分配以及多态中成员方法的特点   Person worker = new Worker(); 子类实例对象地址赋值给父类类型引 ...

  5. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  6. 关于Java中基本类型的长度相关基础知识

    1.  用HeapByteBuffer放int占几个byte? 占4个.而且不论你是放1还是-1还是0xffff. 因为int的长度是4个byte,HeapByteBuffer的存储又是byte数组. ...

  7. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  8. 深入分析 Java 中的中文编码问题

    登录 (或注册) 中文 IBM 技术主题 软件下载 社区 技术讲座 打印本页面 用电子邮件发送本页面 新浪微博 人人网 腾讯微博 搜狐微博 网易微博 Digg Facebook Twitter Del ...

  9. [转]深入分析 Java 中的中文编码问题

    收益匪浅,所以转发至此 原文链接: http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/ 深入分析 Java 中的中文编码问题 编 ...

随机推荐

  1. List,Set,Map三种接口的区别

    set --其中的值不允许重复,无序的数据结构 list   --其中的值允许重复,因为其为有序的数据结构  map--成对的数据结构,健值必须具有唯一性(键不能同,否则值替换)   List按对象进 ...

  2. Windows上模拟Linux环境的软件Cygwin

    Windows上模拟Linux环境的软件Cygwin 2010-10-11 15:19      我要评论(0) 字号:T|T Cygwin是一个用于在Windows上 模拟Linux环境的软件.它可 ...

  3. sql server对并发的处理-乐观锁和悲观锁

    https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...

  4. .net找List1和List2的差集

    有个需求是找两个自定义类泛型集合的差集: class Person { public string Name{get; set;} public string Country{get; set;} } ...

  5. Mybatis 系列3

    系列文章 2 中,我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根节点下面,可配置properties.typeAliases.plugins ...

  6. vue.js中的全局组件和局部组件

    组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能. 组件的使用有三 ...

  7. Hadoop生态圈初识

    一.简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构.Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,则MapReduce为海量 ...

  8. NopCommerce是什么(转自CNSD)

    NopCommerce是什么 nopCommerce--最好的免费购物车!nopCommerce是一个开源的解决方案.它是一个具有综合功能.对于新在线业务来说亦易于使用的解决方案,同时它也是一个功能强 ...

  9. python爬虫入门(六) Scrapy框架之原理介绍

    Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...

  10. Python_pickle模块操作二进制文件

    import pickle b=7 i=13000000 fa=99.056 s='中国人民 123abc' lst=[[1,2,3],[4,5,6],[7,8,9]] tu=(-5,10,8) co ...