s=s+1,s+=1,++1,1++没有区别?
2023-03-31 10:31:17 时间
s=s+1,s+=1,++i,i++没有区别?
有人觉得s=s+1;和s+=1;没什么区别,都是s+1然后在赋值给s,没什么区别,但是++i,和1++是有区别。++i是先加1在赋值,i++是先赋值后加1。真的是这样吗?
s=s+1,s+=1
我们举个例子来验证,short s = 1; s = s + 1;有错吗?s += 1;有错吗?
是不是感觉很面熟,这个不是常见的面试题吗?那你们知道答案吗?
答案
short s = 1; s = s + 1;
由于1是int类型,因此s + 1
运算结果也是int
型,需要强制转换类型才能赋值给short
型。而short s = 1; s += 1;
可以正确编译,因为s += 1;
相当于s = (short)(s + 1);
其中有隐含的强制类型转换。
惊不惊喜,意不意外。
++i,i++
这个我是不是不用多说了,和前面说的一样++i是先加1在赋值,i++是先赋值后加1。我的问题不再这个,而是++i,i++线程安全吗?
不知道了吧,小子,嘿嘿。 测试代码
public class Test {
static int count1 = 0;
static int count2 = 0;
static CountDownLatch countDownLatch = new CountDownLatch(100);
public static void main(String[] args) throws InterruptedException {
TestRunnable testRunnable = new TestRunnable();
for (int i = 0; i < 100; i++) {
new Thread(testRunnable).start();
}
countDownLatch.await();
System.out.println("count1:" + count1);
System.out.println(count2);
}
static class TestRunnable implements Runnable {
private void count() {
for (int i = 0; i < 1000; i++) {
count1++;
++count2;
}
}
@Override
public void run() {
count();
countDownLatch.countDown();
}
}
}
运行结果
//第一次
count1:98867
count2:99013
//第二次
count1:99821
count2:99828
//第三次
count1:100000
count2:100000
//第四次
count1:99672
count2:99682
第五次
count1:98500
count2:98503
是不是知道了,但是知道原因吗?
原因 该语句执行过程如下,先把 i 的值取出来放到栈顶,可以理解为引入了一个第三方变量 k,此时,k的值为i,然后执行自增操作,i的值变为1,最后执行赋值操作 i = k (自增前的值)因此执行结束后,i的值还是0。从上面的分析可知,i = i++语句的执行过程有多个操作组成,不是原子操作,因此不是线程安全的。
解决办法
java.util.concurrent.AtomicInteger
是一个提供原子操作的Integer类,其提供了线程安全且高效的原子操作,是线程安全的。当然不止Integer
Atomic
包有很多线程安全操作,这个需要读者自己去探索。
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十