大家好,今天小编关注到一个比较有意思的话题,就是关于java语言两大变量的问题,于是小编就整理了2个相关介绍Java语言两大变量的解答,让我们一起看看吧。
j***a中什么是null的对象?
一、null是代表不确定的对象
J***a中,null是一个关键字,用来标识一个不确定的对象。因此可以将null赋给引用类型变量,但不可以将null赋给基本类型变量。
比如:int a = null;是错误的。Ojbect o = null是正确的。
二、null本身不是对象,也不是Objcet的实例
null本身虽然能代表一个不确定的对象,但就null本身来说,它不是对象,也不知道什么类型,也不是j***a.lang.Object的实例。
三、J***a默认给变量赋值
在定义变量的时候,如果定义后没有给变量赋值,则J***a在运行时会自动给变量赋值。赋值原则是整数类型int、byte、short、long的自动赋值为0,带小数点的float、double自动赋值为0.0,boolean的自动赋值为false,其他各供引用类型变量自动赋值为null。
四、容器类型与null
List:允许重复元素,可以加入任意多个null。
多个线程可以读一个变量,只有一个线程可以对这个变量进行写,到底要不要加锁?
看你用什么语言开发的,如果是c/C++,***设读写int, int内存里是4Byte,则有可能
写线程写到2byte,就有一个读线程读取数据了,则是就是脏数据了。
原则上不用,但是(敲重点):如果这个项目只是你一人的,并且你永远对它内部逻辑非常清楚,不会因为修改增加逻辑去多个线程写这个变量就不用加锁,反之这如果是个团队项目,并且项目逻辑扩展会越来越复杂,并且团队间项目交接交叉频繁,文档不清,新上手的人不清楚逻辑就会可能对这个变量扩展写逻辑,这种情况就要用锁,这是要解决项目维护和扩展问题,现在n多项目都存在多次交接和扩展后混乱问题。
先说结论:不必要
- 如果不需要可见性,什么都不需要加
- 如果需要保证可见性,则需要加volatile关键字。这里可以加锁,但是没必要,对性能有影响
加锁是因为操作不是原子性的,以i++这个操作来解释,看下面两张图。
i++这个操作需要
- 先将i的值从内存中读出来
- 然后加1
- 最后写回去
看上面第二张图,能很清楚的理解流程吧?
加锁就是保证上面的三步是一个原子操作。
回到问题,这里只有一个线程写,实际没有竞争,所以没必要加锁。
但是,看第一张图,因为有主内存和本地内存的存在
- 线程先写入本地内存
- 然后刷入主内存
- 其它内存同步主内存到工作内存
- 然后从工作内存中读取
一个线程写入后,不能保证其它线程立即看到,这就是可见性问题。
加了volatile关键字后,会强制操作后同步工作内存和主内存,保证其它线程立刻看到。
原则上要加锁。个别简单场景可以不加,比如可以确定读写不会冲突,或者单个简单控制变量考虑volatile。如果是大项目且性能优化指标不是纳秒级的,建议加上锁,免得埋坑。
典型的read write lock场景,J***a中比较经典的ReentrantReadWriteLock。
另外多说一句,当你不确定要不要加锁的时候,就是你需要加锁的时候。
然后你参考MySQL数据库下Innodb存储引擎默认级别是RR,防止脏读,即当我们update一条数据的时候,是加了行锁的,其他的读线程在等待着,所以你需不需要加锁?
不加锁会出现什么问题?
显然会出现脏读的问题!
这也是面试中常见的一种问题,以该题为突破口,带你进入多线程的世界。
其实加锁也很简单,J***a中对该变量进行volatile修饰即可!
不了解volatile的同学需要学习了,本质上是为了保证变量操作时候的内存可见性。
到此,以上就是小编对于j***a语言两大变量的问题就介绍到这了,希望介绍关于j***a语言两大变量的2点解答对大家有用。