这是我参与更文挑战的第7天,活动详情查看: 更文挑战
十七、Java中Wait、Sleep、Yield和join的区别
总体区别
- sleep()和yield()方法定义在Thread类中,而wait()方法定义在Object类中,join由线程对象调用
Wait vs Sleep
- 当一个线程调用wait()方法时,会释放持有对象的管程和锁;但调用sleep()不会释放持有的管程(wait释放cpu资源,也释放锁资源;sleep释放cpu资源,不释放锁资源)
- wait()方法需要在同步代码块中,而sleep方法不需要
- 进入wait状态的线程能够被notify和notifyAll线程唤醒,但是进入sleeping状态的线程不能被notify方法唤醒。
- wait通常有条件地执行,线程会一直处于wait状态,直到某个条件变为真。但是sleep仅仅让你的线程进入睡眠状态。
- wait方法是针对一个被同步代码块加锁的对象,而sleep是针对一个线程。
yield vs sleep
- yield方法会临时暂停当前执行的线程,来让有同样优先级的正在等待的线程有机会执行。如果没有正在等待的线程,或者所有正在等待的线程的优先级都比较低,那么该线程会继续运行。
- yield方法不保证当前的线程会暂停或者停止,但是可以保证当前线程在调用yield方法时会放弃CPU。(让出cpu调度)
join
- 一种特殊的wait,当前运行线程调用另一个线程的join方法,当前线程进入阻塞状态直到另一个线程运行结束等待该线程终止。
- 该方法也需要捕捉异常。
- 等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。
十八、SpringBoot和SpringCloud关系
- SpringBoot专注于快速方便的开发单个个体微服务
- SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供:配置管理、服务发现、断路器、路由、微代理、事件总线、全局所、决策竞选、分布式会话等等集成服务。
- SpringBoot可以离开SpringCloud独立使用,但是SpringCloud离不开SpringBoot,属于依赖关系
- SpringBoot专注于快速、方便开发单个个体微服务,SpringCloud关注全局的服务治理框架
十九、Dubbo和SpringCloud
- 解决的问题域不一样:Dubbo的定位是一款RPC框架,SpringCloud的目标是微服务架构下的一站式解决方案
- SpringCloud:http通信,Dubbo:RPC通信
二十、Spring bean
1. Spring bean的生命周期
- 实例化
AbstractAutowireCapableBeanFactory.doCreateBean中会调用createBeanInstance()方法,从beanDefinitionMap循环读取bean,获取它的属性。然后利用反射,读取对象的构造方法,然后再去创建实例
-
初始化
-
属性赋值
这里可能发生循环依赖的问题
Spring解决这个问题主要靠巧妙的三层缓存,所谓的缓存主要是指这三个map,singletonObjects主要存放的是单例对象,属于第一级缓存;singletonFactories属于单例工厂对象,属于第三级缓存;earlySingletonObjects属于第二级缓存,如何理解early这个标识呢?它表示只是经过了实例化尚未初始化的对象。Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存,这个就是缓存升级。spring在进行对象创建的时候,会依次从一级、二级、三级缓存中寻找对象,如果找到直接返回。由于是初次创建,只能从第三级缓存中找到(实例化阶段放入进去的),创建完实例,然后将缓存放到第一级缓存中。下次循环依赖的再直接从一级缓存中就可以拿到实例对象了。
-
初始化
初始化的过程包括将初始化好的bean放入到spring的缓存中、填充我们预设的属性进一步做后置处理等
实例化和初始化区别:
- 实例化是在jvm堆中创建了这个对象实例,此时它只是空的对象,所有的属性为null
- 初始化过程是将对象依赖的一些属性进行赋值之后,调用某些方法来开启一些默认加载
-
-
使用和销毁
【21】 hashCode()和equals()
hashCode()只有在散列表才有用,在其他条件下没用hashCode()和equals()都定义在Objecet.java中,所以所有对象都有这两个函数- 如果两个对象相同,则hashcode一定也是相同的,反之两个对象的hashcode值相同,并不能证明他们相同
- equals方法被覆盖,则hashCode()方法也必须被覆盖
- hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
【22】equals()和==
-
==:判断两个对象是否相等,即:判断两个对象是不是同一个对象 -
equals()如果不被重写则是判断两个对象地址是否相同;如果被重写则根本重写的函数指定它的功能