Java中的InputStream、FileInputStream、BufferedInputStream和BufferedReader 的区别是什么
Java中的InputStream、FileInputStream、BufferedInputStream和BufferedReader都是输入流相关的类,但是它们在使用和功能上有以下区别:
InputStream是Java IO库中所有输入流的抽象基类,它提供了基本的字节输入操作,如读取字节、跳过字节等。FileInputStream是InputStream的子类,用于从文件中读取数据。
BufferedInputStream是InputStream的装饰类,它提供了缓冲区的支持,可以减少读写磁盘的次数,提高读写效率。
BufferedReader是Reader的装饰类,它提供了字符输入流的缓冲区支持,可以一次读取一行数据,提高读取效率。
因此,如果需要从文件中读取字节数据,可以使用FileInputStream,如果需要增加缓存支持,可以使用BufferedInputStream;如果需要从字符流中读取数据,可以使用BufferedReader。通常情况下,使用带有缓冲区支持的流可以提高读取效率。
Java多线程的状态有以下几种:
新建状态(New):当创建一个线程对象时,它就处于新建状态。
就绪状态(Runnable):当调用线程的start()方法后,线程就进入了就绪状态。此时,线程并未开始执行,只是表示该线程已经准备好可以执行,等待系统调度。
运行状态(Running):当线程获得CPU资源时,就会进入运行状态,开始执行线程的run()方法。
阻塞状态(Blocked):当线程因为某种原因被阻塞时,就会进入阻塞状态。例如,线程在等待某个锁、等待输入/输出等。当线程进入阻塞状态时,它不会消耗CPU资源。
等待状态(Waiting):当线程因为调用了wait()方法而进入等待状态时,它会释放占用的锁,并进入等待队列。当其他线程调用了相应的notify()或notifyAll()方法后,等待线程才会被唤醒并重新进入就绪状态。
计时等待状态(Timed Waiting):当线程调用了sleep()、join()、LockSupport.parkNanos()、LockSupport.parkUntil()等方法时,它会进入计时等待状态。这种状态与等待状态类似,不同的是可以通过指定时间自动唤醒。
终止状态(Terminated):当线程执行完run()方法后,或者因为异常而结束时,它就进入了终止状态。此时,线程的生命周期结束,不再能够被启动或执行。
java 线程池的用途
降低线程的创建和销毁的开销:线程池中已经预先创建了一定数量的线程,并将它们存储在线程池中,可以重复利用,避免了频繁创建和销毁线程的开销,从而提高了程序的执行效率。
提高系统的响应速度:线程池可以充分利用CPU和内存等计算机资源,通过多线程执行任务,使系统可以同时处理多个请求,提高了系统的响应速度和吞吐量。
控制线程的并发数量:线程池可以根据系统负载情况,动态地调整线程的数量,避免因线程数量过多导致系统资源不足的问题。
提高代码的可维护性:使用线程池可以将线程的创建和管理与业务逻辑分离开来,使代码更加清晰、易读、易维护。
提高程序的稳定性:线程池可以对线程进行统一管理,避免了线程数量过多而导致的系统崩溃等问题,从而提高了程序的稳定性。
java 线程池有哪些 关键配置
核心线程数(corePoolSize):表示线程池中一直保持的线程数量,即使它们闲置也不会被回收。
最大线程数(maximumPoolSize):表示线程池中最多可以容纳的线程数量,包括闲置和工作中的线程。
队列(workQueue):表示用于存储等待执行的任务的阻塞队列。Java提供了多种类型的队列实现,如ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue等。
空闲线程存活时间(keepAliveTime):表示当线程池中的线程数量大于核心线程数时,闲置线程的存活时间,超过此时间就会被回收。
时间单位(TimeUnit)
线程工厂(ThreadFactory):表示用于创建新线程的工厂类,可以通过它自定义线程的名称、优先级等属性。
这些关键配置可以通过调用线程池的构造函数或者setter方法进行配置。不同的应用场景可能需要不同的配置,合理地设置这些参数可以使线程池的执行效率更高,同时也可以避免由于线程过多或过少而导致的资源浪费或任务阻塞等问题。
Java线程池有以下几个常用的配置:
corePoolSize:线程池中保留的核心线程数,即使线程处于空闲状态也不会被回收。
maximumPoolSize:线程池允许的最大线程数,超过这个数量的线程将被拒绝。
keepAliveTime:非核心线程空闲时的存活时间,超过这个时间将被回收。
workQueue:任务队列,用于存放还未执行的任务,有以下几种实现方式:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue等。
threadFactory:线程工厂,用于创建线程。
rejectedExecutionHandler:拒绝策略,用于处理拒绝的任务。有以下几种实现方式:AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy。
allowCoreThreadTimeOut:是否允许核心线程超时退出,默认为false。
通过合理配置线程池的参数,可以提高程序的执行效率和响应速度,避免因线程数量过多或过少导致的资源浪费和阻塞等问题。
truncate 和 delete的区别是什么
在关系型数据库中,truncate和delete都是用来删除表中的数据,但它们的实现方式和效果略有不同,具体区别如下:
truncate会删除表中的所有数据,并且会重置自增长的ID等状态,而delete只是删除符合条件的行。
truncate是DDL语句(数据定义语言),执行时会自动提交事务,无法回滚,而delete是DML语句(数据操作语言),可以在事务中执行,并可以回滚。
truncate删除表中的数据的速度比delete快,因为它是通过直接清空表中数据的方式来实现的,而delete需要对每行进行操作。
truncate会释放表的存储空间,而delete不会,所以在需要释放存储空间的时候可以使用truncate。
综上所述,如果需要删除表中的所有数据并重置表状态,可以使用truncate,如果需要删除符合条件的数据并可以回滚,可以使用delete。同时,需要注意truncate和delete的使用场景和效果,避免出现意外的错误。
Spring Boot支持多种方式读取配置文件,包括:
配置文件默认读取路径:Spring Boot会默认从classpath下读取名为application.properties或application.yml的配置文件。
自定义配置文件名和位置:可以通过在application.properties中设置spring.config.name和spring.config.location属性来自定义配置文件的文件名和路径。
命令行参数:可以通过在命令行中使用--spring.config.name和--spring.config.location参数来指定配置文件的文件名和路径。
环境变量:可以使用环境变量来设置配置文件的文件名和路径,如SPRING_CONFIG_NAME和SPRING_CONFIG_LOCATION。
Java系统属性:可以通过设置Java系统属性来指定配置文件的文件名和路径,如-Dspring.config.name和-Dspring.config.location。
配置文件的优先级:Spring Boot支持多个配置文件,如application.properties和application-dev.properties。在同一个配置属性在多个配置文件中都有定义时,Spring Boot会按照一定的优先级进行配置的合并和覆盖。
在实际应用中,我们可以根据不同的场景和需求,选择适合自己的配置方式,方便地管理和修改应用的配置信息。