开发设计

Java并发编程问题汇总五:ThreadLocal

ThreadLocal是比较常用的多线程工具,有效理解ThreadLocal的内部原理,对自信地使用它具有益处。

许多朋友认为它是多线程环境下处理数据共享的手段,其实这种想法是对ThreadLocal最大的误解。

内存数据共享是并发编程中需要处理的一大难点,但是ThreadLocal却不是为了解决数据共享问题而生的。顾名思义,ThreadLocal为每个线程提供一个本地(本线程)副本,而这些副本之间,从出生到结束,都是没有丝毫联系的,它们仿佛是生活在平行宇宙中的同名个体,之间没有交际,互补影响,更何谈数据共享。

HBase 集群复制

HBase本身支持集群复制,也就是说,制定一个备集群,HBase的RegionServer会异步(或同步)的将数据同步到备集群中。

这个功能看似简单,其实非常有用。首先,备集群本身是非常有用的,在某些系统中,需要跑一些离线任务半实时的统计,直接在线上HBase跑的话,容易占据太多资源,造成抖动。所以通过备集群来做这件事情是一个不错的选择。当然,我认为SnapShot应该是比这个更靠谱一点。

另外,这里的备集群并不一定是HBase集群,HBase提供了一个抽象,可以让用户自定义BaseReplicationEndpoint,可以将需要备份的数据自定义得写到某个地方,这就提供了无限的想象力。

HTTPS

20200727220356

因为目前的工作是与对象存储相关的,所以与HTTP协议打交道还算比较多,对HTTP一些基本的概念有一定了解,但是始终没有自己完整厘清过HTTPS的工作流程,今天整理一下思路。

慎用FileBackedOutputStream

在项目中遇到一个FileBackedOutputStream的坑,在此记录一下。

因为某些原因,需要实现一个ResettableInputStream,大家都知道,JDK中,ByteArrayInputStream是可以mark、reset的,但是代价就是将所有数据都load进内存,在数据量较大时,这是无法接受的。因为我们需要的是任意的在流中穿梭的能力,这时候,可以借助磁盘来完成这一功能。索性,Guava中提供了一个类,FileBackedOutputStream,将数据写入其中之后,如果数据超过一定限度,它就会将数据写入磁盘。

FileBackedOutputStream的构造函数如下所示,里面提供了一个叫supplier的类,这个类作为OutputStream的出口。这里应该注意一下,如果resetOnFinalize这一个参数如果设为true的话,supplier会重写finalize方法,里面调用reset操作。这也是本篇文章出现的原因。

  public FileBackedOutputStream(int fileThreshold, boolean resetOnFinalize) {
    this.fileThreshold = fileThreshold;
    this.resetOnFinalize = resetOnFinalize;
    memory = new MemoryOutput();
    out = memory;

    if (resetOnFinalize) {
      supplier = new InputSupplier<InputStream>() {
        @Override
        public InputStream getInput() throws IOException {
          return openStream();
        }

        @Override protected void finalize() {
          try {
            reset();
          } catch (Throwable t) {
            t.printStackTrace(System.err);
          }
        }
      };
    } else {
      supplier = new InputSupplier<InputStream>() {
        @Override
        public InputStream getInput() throws IOException {
          return openStream();
        }
      };
    }
  }

  public InputSupplier<InputStream> getSupplier() {
    return supplier;
  }

MapReduce

MapReduce是三篇经典分布式论文中与关于批量计算的一篇,相比之下,MapReduce较为容易理解。对于MapReduce,我了解不够深入,仅限于阅读过论文,写过简单的HadoopMapReduce程序,完成了6.824的模拟例题。下面,我将会简单整理一下我对MapReduce的理解。