Java7新特性 - AutoCloseable

本文介绍了Java 1.7引入的AutoCloseable接口及其在资源管理中的作用,通过案例展示了如何使用try-with-resources语句自动关闭如Lock、PreparedStatement等资源,避免了手动释放资源可能导致的遗忘或顺序错误问题。同时,文章给出了关闭多个资源的顺序,并强调了其在减少潜在错误和提高代码可读性方面的价值。
摘要由CSDN通过智能技术生成

🍊 概述

JDK在1.7之后出现了自动关闭类的功能,该功能的出现为各种关闭资源提供了相当大的帮助,这里我们谈一谈自动关闭类。
JDK1.7之后出现了一个重要的接口,以及改造了一个重要的方法结构:
1、AutoCloseable自动关闭接口
2、try(){}–catch{}–finally{}
相应的 一些资源也实现了该接口,如PreparedStatement、Connection、InputStream、OutputStream等等资源接口。

一句话: 实现AutoCloseable接口,覆盖close方法,把原来要写finally中释放资源的动作,放入到close方法中去执行,而这个执行是jvm自己去执行.
什么样子的情况下可以去做呢?–如果有try(){}–catch{}–finally{}

  • 接口的实现类要重写close()方法,
  • 将要关闭的资源定义在try()中,这样当程序执行完毕之后,资源将会自动关闭。
  • 自定义类如果要进行自动关闭,只需要实现AutoCloseable接口重写close()方法即可

同时也只有实现了AutoCloseable接口才能将,自定义类放入到try()块中,否则编译不能通过,举例说明

public class ReadTxt extends AutoClassable {
	@Override
	public void close() throws Exception {
		System.out.println("ReadTxt close");
	}
 
	public String readTextValue(String path){
		StringBuffer sb = new StringBuffer();
		try(BufferedReader br = new BufferedReader(new FileReader(path))){
			int line;
			while((line = br.read())!=-1){
				sb.append(br.readLine()+"\n")
			}
		}
		return sb.toString();
	}
}
 
class MainTest {
	public static void main(String[] args) {
		try (ReadTxt rt = new ReadTxt()) {
			String line = rt.readTextValue("G:\\学习文档\\test.txt");
			System.out.println(line);
		}
	}
}

🍊案例分析

🍌上锁为例

public class MyLockDemo {
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        try {
            lock.lock();
            System.out.println("1-----加锁成功!!!");
            System.out.println("2-----开始执行业务逻辑");
            Thread.sleep(3000);
            System.out.println("3-----业务执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            System.out.println("4----释放锁资源");
        }
    }

}

🍌 资源释放的问题?

通过上面的代码我们发现,在开发中锁是释放必须要做得事情,所以就把放在finally中来执行。但是在开发中往往很多的开发中,都会忘记释放锁或者忘记把锁的释放放入finally中,就造成死锁现象,这个很危险的操作和行为。

🍌如何解决遗忘的问题呢?

使用AutoCloseable接口覆盖close方法

🍌改进步骤

public class MyLock implements AutoCloseable{

    Lock lock = new ReentrantLock();

    // 加锁
    public void lock() {
        lock.lock();
    }

    // 释放锁
    public void unlock() {
        lock.unlock();
    }


    @Override
    public void close() throws Exception {
        unlock();
        System.out.println("4----释放锁资源");
    }
}

改进

public class MyLockDemo {
    public static void main(String[] args) {
        try (MyLock lock = new MyLock();){
            lock.lock();
            System.out.println("1-----加锁成功!!!");
            System.out.println("2-----开始执行业务逻辑");
            Thread.sleep(3000);
            System.out.println("3-----业务执行完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }//        finally {
//            // 不需要定义了.因为会自动去释放资源
//            lock.unlock();
//        }
    }
}

🍌关闭多个资源怎么办呢?

例如:在JDBC中,我们需要关闭connection statement resultset 这些资源
并且资源的关闭也是有先后顺序的
案例:

public class MyLock implements AutoCloseable{

    Lock lock = new ReentrantLock();

    // 加锁
    public void lock() {
        lock.lock();
    }

    // 释放锁
    public void unlock() {
        lock.unlock();
    }


    @Override
    public void close() throws Exception {
        unlock();
        System.out.println("4--lock--释放锁资源");
    }
}
public class MyLock2 implements AutoCloseable{

    Lock lock = new ReentrantLock();

    // 加锁
    public void lock() {
        lock.lock();
    }

    // 释放锁
    public void unlock() {
        lock.unlock();
    }


    @Override
    public void close() throws Exception {
        unlock();
        System.out.println("4--lock2--释放锁资源");
    }
}
public class MyLockDemo {
    public static void main(String[] args) {
        try (MyLock2  lock2 = new MyLock2();MyLock  lock = new MyLock()){
            lock.lock();
            lock2.lock();
            System.out.println("1-----加锁成功!!!");
            System.out.println("2-----开始执行业务逻辑");
            Thread.sleep(3000);
            System.out.println("3-----业务执行完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }

}

此时执行的结果是:

1-----加锁成功!!!
2-----开始执行业务逻辑
3-----业务执行完毕
4--lock--释放锁资源
4--lock2--释放锁资源

我们接着测试看是否有顺序

  try (MyLock  lock = new MyLock();MyLock2  lock = new MyLock2()){
            lock.lock();
            lock2.lock();
            System.out.println("1-----加锁成功!!!");
            System.out.println("2-----开始执行业务逻辑");
            Thread.sleep(3000);
            System.out.println("3-----业务执行完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }

结果如下

1-----加锁成功!!!
2-----开始执行业务逻辑
3-----业务执行完毕
4--lock2--释放锁资源
4--lock--释放锁资源

所以,释放资源的顺序是有的,取决于对象的前后

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值