Java 关闭BufferedReader类的目的是什么?它是否会影响时间/记忆(如果如何)?

Java 关闭BufferedReader类的目的是什么?它是否会影响时间/记忆(如果如何)?,java,Java,黑马21号代码部队竞赛355 Q_A public class A_VanyaAndFence { public static void main(String args[])throws IOException{ BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st=new StringTokenizer(br.readLine()); int

黑马21号代码部队竞赛355 Q_A

public class A_VanyaAndFence {
public static void main(String args[])throws IOException{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st=new StringTokenizer(br.readLine());
    int n,h;
    n=Integer.parseInt(st.nextToken());
    h=Integer.parseInt(st.nextToken());
    st=new StringTokenizer(br.readLine());
    //int arr[]=new int[n];
    int cnt=0;
    for(int i=0;i<n;i++){
        int a=Integer.parseInt(st.nextToken());
        if(a>h){
            cnt+=2;
        }
        else
            cnt++;
    }
    System.out.println(cnt);
}
公共A级_VanyaAndFence{
公共静态void main(字符串args[])引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
StringTokenizer st=新的StringTokenizer(br.readLine());
int n,h;
n=Integer.parseInt(st.nextToken());
h=Integer.parseInt(st.nextToken());
st=新的StringTokenizer(br.readLine());
//int arr[]=新的int[n];
int-cnt=0;
对于(int i=0;ih){
cnt+=2;
}
其他的
cnt++;
}
系统输出打印项次(cnt);
}
这个代码花费了155ms,20100kb

public class A_VanyaAndFence {
public static void main(String args[])throws IOException{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st=new StringTokenizer(br.readLine());
    int n,h;
    n=Integer.parseInt(st.nextToken());
    h=Integer.parseInt(st.nextToken());
    st=new StringTokenizer(br.readLine());
    //int arr[]=new int[n];
    int cnt=0;
    for(int i=0;i<n;i++){
        int a=Integer.parseInt(st.nextToken());
        if(a>h){
            cnt+=2;
        }
        else
            cnt++;
    }
    System.out.println(cnt);
    br.close();
}
公共A级_VanyaAndFence{
公共静态void main(字符串args[])引发IOException{
BufferedReader br=新的BufferedReader(新的InputStreamReader(System.in));
StringTokenizer st=新的StringTokenizer(br.readLine());
int n,h;
n=Integer.parseInt(st.nextToken());
h=Integer.parseInt(st.nextToken());
st=新的StringTokenizer(br.readLine());
//int arr[]=新的int[n];
int-cnt=0;
对于(int i=0;ih){
cnt+=2;
}
其他的
cnt++;
}
系统输出打印项次(cnt);
br.close();
}
}

这个代码花了124ms,20100kb


为什么?

即使影响可能不会太大,但当阅读的文本不是太广泛时。这主要是对记忆的影响,其次是对时间的影响,尤其是在阅读大量文本时。close()方法不仅关闭流,还释放与BufferReader/Reader类实现关联的系统资源

文件描述符是操作系统中的一种资源,一旦在BufferReader上调用close(),它就会被释放。在最新版本的Java中,垃圾收集器时不时地运行,应该为您调用close()方法,并处理掉废弃的文件描述符。但在那之前,这个可怜的家伙会在拐角处徘徊

假设您在一个大循环中初始化BufferReader对象,而不是在循环中关闭相同的对象。您的循环可能会在垃圾回收器执行其工作之前提取废弃的文件描述符。 这也是一个很好的编程实践,因为一旦流被关闭,其他BufferReader/Reader方法将通过IOExceptions(另一个close()方法将不起任何作用)

参考:

话虽如此,我自己也参与了一个广泛的项目,在这个项目中,关闭每个实例的BufferReader变得很困难,我确实在一些场合避免了它。它对输出和程序执行没有任何值得注意的影响。BufferReader对象最终将被垃圾收集器丢弃。大多数现实世界的应用程序可能对垃圾收集的性能感到满意,并且在时间和内存方面不会显示出任何显著的影响


希望这能有所帮助。

在需要资源时使用资源,在不再需要资源时释放资源是很标准的做法。你的测试也很幼稚,所以你不应该根据它得出结论。@Kayaman。这个问题仍然很有趣,因为它问我们为什么要做一件我们经常认为理所当然应该做的事情。答案很简单:资源是有限的,但初学者并不总是容易理解。我认为您不应该关闭
BufferedReader
,因为这会产生关闭
系统的效果。如果你不打开一个流,你就不应该关闭它。如果你问为什么它花费的时间更少,我会指出,你似乎在看每个程序的一次运行——运行时间可能受到很多因素的影响,包括当时CPU的负载。这就是为什么大多数性能基准都会进行大量的测试,并使用统计数据(或者在非常简单的情况下,使用平均值)来获得不同场景中的一般运行时间以进行比较。一次运行通常会受到太多变量的影响,无法进行有意义的比较-我建议对多次运行求平均值,并查看结果是否匹配既不匹配
BufferedReader
,也不匹配其超类实现
finalize()
;因此,流不会因为垃圾收集而被清除(而且无论如何,您不应该依赖于
finalize()
被调用)。所以这是一种危险的策略,我在3/4的评论中并没有建议使用垃圾收集作为一种策略,事实上,我建议如果您已经实例化了BufferReader作为一种良好的实践,那么应该调用close()。当您建议您不应该关闭BufferReader,因为它也会关闭输入流时,您认为与BufferReader关联的系统资源会发生什么情况?“大多数真实世界的应用程序会对垃圾收集的性能非常满意”听起来很像是建议将GC作为一种策略。“当您建议不应关闭BufferReader时,因为它也会关闭输入流“我建议,如果您自己没有打开输入流,就不应该关闭
BufferedReader
,原因是传递给您的人不知道您已经关闭了它,没有尝试IO操作,也没有捕捉到故障。我的意思是解释为什么它如果不关闭,显然不会产生很大的影响。阅读前3-4段。任何地方都没有“我推荐”。但明确提到什么是好的做法。