byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值
不是;
1、包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是
2、包装类型是引用的传递,基本类型是值的传递
3、声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间
4、存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们
5、初始值不同,eg: int的初始值为 0 、 boolean的初始值为false 而包装类型的初始值为null
6、使用方式不同,基本数据类型直接赋值使用就好 ,而包装类型是在集合如 coolection Map时会使用
PS:jvm在运行时创建了一个缓存区域,并创建了一个Integer的数组。这个数组存储了-128至127的值。因此如果Integer的值在-128至127之间,则是去缓存里面获取。此时,若Integer用“=”赋值,可以直接用==比较。(因为会指向同一内存地址)可类比String。
答案:https://my.oschina.net/u/566591/blog/1619912
答案:https://blog.csdn.net/he90227/article/details/82258930
https://segmentfault.com/a/1190000014595928
答案:https://blog.csdn.net/perfectnihil/article/details/90234251
原理:先查询缓存中有没有要的数据,如果有,就直接返回缓存中的数据。
如果缓存中没有要的数据,才去查询数据库,将得到数据先存放到缓存中,然后再返回给java。
优点:
1、 减少了对数据库的读操作,数据库的压力降低
2、 加快了响应速度
缺点:
1、 因为内存断电就清空数据,存放到内存中的数据可能丢失
2、 缓存中的数据可能与数据库中数据不一致
3、 内存的成本高
4、 内存容量相对硬盘小
参考:https://blog.csdn.net/fengqiangdu/article/details/96475383
思路:扯了一下区别然后扯了一下底层实现
答案:
一、原始构成
synchronized是关键字属于JVM层面,monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖monitor对象只有在同步代码块和同步方法中才能调用wait/notify等方法)
Lock是具体的类,是api层面的锁;
二、使用方法
synchronized不需要用户手动释放锁,synchronized代码执行完成以后系统会自动让线程释放对锁的占有
ReentrantLock则需要用户手动去释放锁,若没有主动释放锁,就有可能导致死锁现象。需要使用lock()和unlock()方法配合try finally语句块来完成。
三、等待是否可以中断
synchronized不可中断,除非抛出异常或者正常运行完成。
ReetrantLock可中断,
1. 设置超时方法tryLock(long timeout, TimeUnit unit);
2.lockInterruptibly()放入代码块中,调用interrupt()方法可中断;
四、加锁是否公平
synchronized是非公平锁
ReentrantLock默认是非公平锁,可设置为公平锁。
五、锁绑定多个条件condition
synchronized没有;
ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个,要么唤醒全部线程。
六、案例
题目:多线程之间按找顺序调用,实现A->B->C三个线程启动,要求如下:
AA打印5次,BB打印10次,CC打印15次,重复上述过程10次.
class ShareResource{
private int number = 1; // A:1, B:2, C:3
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public void print5(){
try {
lock.lock();
while (number != 1){
conditionA.await();
}
for (int i = 1; i <= 5; i++){
System.out.print("A");
}
System.out.println();
number++;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(){
try {
lock.lock();
while (number != 2){
conditionB.await();
}
for (int i = 1; i <= 10; i++){
System.out.print("B");
}
System.out.println();
number++;
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(){
try {
lock.lock();
while (number != 3){
conditionC.await();
}
for (int i = 1; i <= 15; i++){
System.out.print("C");
}
System.out.println();
number = 1;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class SynchronizedLockDifference {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print5();
}
}, "A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print10();
}
}, "B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print15();
}
}, "C").start();
}
}
输出结果:
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
详解:https://blog.csdn.net/hefenglian/article/details/82383569
答案:https://blog.csdn.net/gududedabai/article/details/80326129
答案:https://blog.csdn.net/weixin_41282397/article/details/87618004
答案:https://blog.csdn.net/qq_28000789/article/details/86499750
答案:https://www.cnblogs.com/ghl0518/p/11057589.html
https://blog.csdn.net/zy1471162851/article/details/88703049
答案:
1.redis 核心就是 如果我的数据全都在内存里,我单线程的去操作 就是效率最高的,为什么呢,因为多线程的本质就是 CPU 模拟出来多个线程的情况,这种模拟出来的情况就有一个代价,就是上下文的切换,对于一个内存的系统来说,它没有上下文的切换就是效率最高的。redis 用 单个CPU 绑定一块内存的数据,然后针对这块内存的数据进行多次读写的时候,都是在一个CPU上完成的,所以它是单线程处理这个事。在内存的情况下,这个方案就是最佳方案 —— 阿里 沈询
2.详解:https://blog.csdn.net/u010122604/article/details/92829855
7种事务的传播机制(可通过spring配置或注解来设置)
REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。
SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。
MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。
REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
NEVER:无事务执行,如果当前有事务则抛出Exception。
NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。
注解配置时如:@Transactional(propagation=Propagation.REQUIRED)
详解:https://blog.csdn.net/GarfieldEr007/article/details/83052636
答案:https://www.cnblogs.com/rayduan/p/xrq730.html
https://blog.csdn.net/zsj777/article/details/80353464
答案:一文搞懂JVM内存结构
答案:https://www.cnblogs.com/gl-developer/p/6102282.html
答案:https://blog.csdn.net/huangwei18351/article/details/81369002
最详细的答案:
https://blog.csdn.net/brucexiajun/article/details/100996668