s=s+1,s+=1,++1,1++没有区别?

简介: s=s+1,s+=1,++1,1++没有区别?

s=s+1,s+=1,++1,1++没有区别?

有人觉得s=s+1;和s+=1;没什么区别,都是s+1然后在赋值给s,没什么区别,但是++1,和1++是有区别。++1是先加1在赋值,1++是先赋值后加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);其中有隐含的强制类型转换。

惊不惊喜,意不意外。

++1,1++

这个我是不是不用多说了,和前面说的一样++1是先加1在赋值,1++是先赋值后加1。我的问题不再这个,而是++1,1++线程安全吗?

不知道了吧,小子,嘿嘿。
测试代码

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包有很多线程安全操作,这个需要读者自己去探索。

相关文章
|
20天前
|
索引
for in 和 for of的区别
for in 和 for of的区别
|
23天前
知识和智慧的联系和区别
知识和智慧的联系和区别
18 0
|
2月前
a++与++a的区别
a++与++a的区别。
16 4
|
4月前
|
数据可视化 数据挖掘
jupternotebook和jupterLab有什么区别?
jupternotebook和jupterLab有什么区别?
70 0
|
7月前
bis和bic区别与实现
bis和bic区别与实现
56 0
|
8月前
|
索引
for each和for of的区别
for each和for of的区别
|
11月前
|
安全 前端开发 Java
WebMvcConfigurationSupport 和 WebMvcConfigurer 区别你知道吗
WebMvcConfigurationSupport 和 WebMvcConfigurer 的使用过程中你是否踩坑了它们的区别是什么快来看看吧
337 0
rsaCheckV2 和rsaCheckV1的区别分享
说明: 目前支付宝的SDK验签方法主要有两种一种是rsaCheckV1一种是rsaCheckV2 两种验签方法用于不同的接口的返回参数验签 1.rsaCheckV1验签方法   rsaCheckV1验签方法主要用于支付接口的返回参数的验签比如:当面付,APP支付,手机网站支付,电脑网站支付 这些接口都是使用rsaCheckV1方法验签的 2.
3412 0
|
新零售 网络协议 网络安全
常用的高防有哪几类?主要的区别是什么?
有一些用户受到DDOS攻击的时候,不知道自己该选择什么样的高防来防御攻击,墨者安全今天主要讲下常用的高防有哪几类?以及主要的区别?高防主要分为HTTPS高防、TCP高防、CDN高防、香港高防、海外高防。