栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java7新特性 - AutoCloseable

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java7新特性 - AutoCloseable

 概述

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--释放锁资源

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332576.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号