- 1.sleep()和wait()的区别?
sleep()是thread的方法,wait()是object中的方法。
sleep()使当前线程暂停指定时间,让出cpu,但是监控状态一直保存着,当指定的时间到了又会自动恢复运行状态。
sleep()不会释放锁,wait()会放弃锁,只有对此对象调用notify()后对象才会进入线程池准备状态。
sleep()可以在任何地方使用,wait()只能在同步块和同步方法中进行使用。
sleep()需要捕获异常,wait()不需要。
- 2.sleep()需要捕获异常的原因?
Thread.sleep()是让线程休眠。在这种睡眠状态下,你可能调用interrupte来终止线程,这样就会抛出InterruptException,只有捕获异常进行处理,才能正确的终止线程。
- 3.Thread.sleep(0)有什么意义?
当前线程不一定会被唤醒,虽然休眠了0秒,但是执行sleep方法后,不仅仅会休眠,还会使CPU资源重新分配,因此,Thread.sleep(0)就是触发操作系统进行一次资源重新分配,竞争结果可能当前线程仍然获得CPU的控制权,也有可能其他线程获得CPU的控制权,这也是我闷经常在一些大循环中使用Thread.sleep(0)的原因,因为这样接给了其他线程获取CPU控制权的权利,这样一些空能就不会假死在那里。参考链接
- 4.spring、springMVC、springBoot区别?
Spring框架最核心的就是所谓的依赖注射和控制反转。完全解耦类之间的依赖关系,一个类如果要依赖什么,那就是一个接口。至于如何实现这个接口,这都不重要了。只要拿到一个实现了这个接口的类,就可以轻松的通过xml配置文件把实现类注射到调用接口的那个类里。所有类之间的这种依赖关系就完全通过配置文件的方式替代了。
springMVC是spring提供的一款灵活又强大的web框架,通过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。主要目的是对业务进行分层和解耦,灵活性强,易拓展
springMVC缺点:Servlet API 耦合,难以脱离容器独立运行,配置过于冗余
springBoot主要是为了使项目的配置更加简单,可以直接以jar包形式运行项目,内嵌容器,可以使项目更方便快速运行。
springBoot提供了一系列的startPom简化我们的maven依赖。
联系:
Spring 最初利用“工厂模式”( DI )和“代理模式”( AOP )解耦应用组件。按照这种模式搞了一个 MVC 框架(一些用 Spring 解耦的组件),用开发 web 应用( SpringMVC )。后来发现每次开发都要搞很多依赖,写很多样板代码,使代码臃肿而麻烦,于是聪明的前人整理了一些懒人整合包( starter ),这套就是 Spring Boot 。
- 5.spring的事务管理
确保事物的完整性和一致性
5.1事物的四个特性(ACID):
原子性:都成功或者都失败。
一致性:事物完成后,不管成功或者失败,必须确保它所建模的业务处于一致的状态。
隔离性:可能有许多事物处理相同的数据,因此个事物都应该隔离起来,不要互相干扰。
持久性:一旦事物完成,无论发生什么系统错误,结果都不应该不受影响。
5.2事物的传播行为:
当事物方法被另一个事物方法调用时,必须指定事物应该如何传播
(1):propagation_required:required(必须)。默认值:A如果有事物,B将使用该事物;若A没有事物,B创建一个新事物。
(2):propagation_supports:supports(支持)。A如果有事物,B将使用该事物;若A没有事物,B将以非事物运行。
(3):propagation_mandatory:mandatory(强制)。A如果有事物,B将使用该事物;A如果没有事物,B将抛异常。
(4):propagation_requireds_new:requireds_new(必须新的)。A如果有事物,将A事物挂起,B创建一个新事物;若A没有事物,B将创建一个新事物。
(5):propagation_not_supports:not_supports(不支持)。A如果有事物,将A事物挂起,B以非事物方式运行;若A没有事物,B直接以非事物方式运行。
(6):propagation_never:never(从不)。A如果有事物,B抛异常;若A没有事物,B将以非事物方式运行。
(7):propagation_nested:nested(嵌套)。A和B底层采用保存点机制,形成嵌套事物。
5.3事物的隔离级别:
定义了一个事物可能受其他并发事物影响的程度。
并发事物引起的问题:多个事物并发运行,经常会操作相同的数据来完成各自的任务,并发虽然是必须的,但可能出现问题。
(1):脏读-一个事物读取了另一个事物未提交的数据,如果改写在稍后回滚了,读取到的数据就是无效的。
(2):不可重复读-发生在一个事物执行两次查询或者以上,但是每次的数据不同,这是因为在读之间其它数据修改了数据。
(3):幻读-与不可重复读类似,事物多个查询相同的数据,发现前面查询没有的数据,这是因为其它数据插入了记录。
隔离级别:spring的TransactionDefinition.class中用常量表示(-1、0、1、2、4、8)
(1):isolation_default:使用后端数据库的隔离级别。
(2):isolation_read_uncommitted:最低的隔离级别,容易读取未提交的数据变更,可能导致脏读、幻读和不可重复读。
(3):isolation_read_committed:允许读取并发事物已经提交的数据,可以防止脏读的情况,但无法避免幻读和不可重复读。
(4):isolation_repeatable_read:对同一字段多次读取数据都是一致的,除非数据是当前自己的事物修改的,可以阻止脏读和不可重复读,幻读仍然有可能发生。
(5):isolation_serializable:最高的隔离级别,也是最慢的隔离级别,能防止所有的情况,因为它完成是通过锁定事物所有的数据表来实现的。
5.4Spring 编程式事务和声明式事务的区别
编程式事务处理:所谓编程式事务指的是通过编码方式实现事务,允许用户在代码中精确定义事务的边界。即类似于JDBC编程实现事务管理。管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。
声明式事务处理:管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
简单地说,编程式事务侵入到了业务代码里面,但是提供了更加详细的事务管理;而声明式事务由于基于AOP,所以既能起到事务管理的作用,又可以不影响业务代码的具体实现
注意:不可重复读是由于修改导致的,幻读是由于增加和删除导致的。
- 6.本地事物和分布式事物
- 7.jvm
- 8.如何获取线程的状态
- 9.线程的生命周期
- 10.继承Thread线程异常只能tryCatch不能throws
1.在子类覆盖父类的时候,子类抛出的异常必须是和父类异常一致,或者是父类异常的子类。
2.如果父类或者接口没有异常抛出,子类覆盖父类时出新异常,只能try不能throws。
在Thread类中的run()方法是没有申明抛出异常的,所以继承Thread类,只能自己处理异常,不可以抛出来。
- 11.分布式锁
- 12.分布式事物
- 13.多线程的作用
系统中遇到高并发,并行的情况下为了解决负载均衡的问题,就会使用到线程,线程可以提高CPU的利用率。
只有当机器为双核或者双CPU的情况下,才是真正意思上的多线程。
- 14.线程死锁
两个线程相互等待的状态,就形成了死锁。
解锁死锁:加大锁的力度。
- 15.线程同步
多个线程同时访问统一资源时,线程与线程之间协调的这一过程就成为线程同步。
synchronized():同步方法,锁定线程,同步方法就是执行方法的时候当前对象被锁定。
(锁定当前方法的对象,必须等当前线程执行结束才能执行下一个线程)。
线程的同步就是使线程处在一个安全化的状态。
- 16线程常用方法
shutDown()方法:结束线程,调用此方法可以定义一个变量,如:boolean flag = true。
join():合并某个线程。
yield():合并某个线程。
setPriority():设置线程的优先级。
- 17.线程和进程的区别
进程有独立的内存和空间,线程只是进程的一个执行单元,相同的线程是共享内存空间的。
所以:进程运行时对内存的消耗开销比较大,线程比较节省内存。