我是靠谱客的博主 奋斗香水,最近开发中收集的这篇文章主要介绍多线程创建FileSystem,当close时导致其他的FileSystem关闭,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

问题1:当我们使用FileSystem.get(conf)时会创建几个实例

针对这个问题我们进行代码测试

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;

import java.io.IOException;
import java.util.List;

public class ThreadTest extends Thread{
    private FileSystem fs;
    public FileSystem getFs() {
        return fs;
    }
    public static void main(String[] args) throws InterruptedException {
        ThreadTest[] threads = new ThreadTest[10];
        for(int i=0;i<10;i++){
            threads[i]=new ThreadTest();
            threads[i].start();
        }
        Thread.sleep(5000);
        FileSystem fs = threads[0].fs;
        for(ThreadTest thread:threads){
            System.out.println(fs == thread.fs);
        }
    }
    @Override
    public void run() {
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS","hdfs://192.168.56.1:8020");
        try {
            fs = FileSystem.get(conf);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行等到结果全为true。

分析:多线程创建FileSystem时,创建的FileSystem实例其实只有一个,所以当我们执行close类时就会导致其他线程中使用 的FileSystem为空。

问题2:为什么导致这个问题呢

分析:查看FileSystem的源码我们可以很容易看到原因,在FileSystem中有Map类存放key和FileSystem,key的生成有uri和configure生成,Key重写了equals方法,所以当uri和configure相同时生成的FileSystem也是相同的

public boolean equals(Object obj) {
        if (obj == this) {
          return true;
        }
        if (obj != null && obj instanceof Key) {
          Key that = (Key)obj;
          return isEqual(this.scheme, that.scheme)
                 && isEqual(this.authority, that.authority)
                 && isEqual(this.ugi, that.ugi)
                 && (this.unique == that.unique);
        }
        return false;        
      }
synchronized (this) { // refetch the lock again
        FileSystem oldfs = map.get(key);
        if (oldfs != null) { // a file system is created while lock is releasing
          fs.close(); // close the new file system
          return oldfs;  // return the old file system
        }
        
        // now insert the new file system into the map
        if (map.isEmpty()
                && !ShutdownHookManager.get().isShutdownInProgress()) {
          ShutdownHookManager.get().addShutdownHook(clientFinalizer, SHUTDOWN_HOOK_PRIORITY);
        }
        fs.key = key;
        map.put(key, fs);
        if (conf.getBoolean("fs.automatic.close", true)) {
          toAutoClose.add(key);
        }
        return fs;
      }

解决:有两种解决办法

1.添加 fs.hdfs.impl.disable.cache 参数为true

2.使用 newInstance创建FileSystem

最后

以上就是奋斗香水为你收集整理的多线程创建FileSystem,当close时导致其他的FileSystem关闭的全部内容,希望文章能够帮你解决多线程创建FileSystem,当close时导致其他的FileSystem关闭所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部