Java源代码中赋值临时变量的操作

复制变量到临时变量的作用

  • 实例
  • 优点
  • 缺点

1、实例

StringBuilder的父类AbstractStringBuilder的**appendNull()**方法

private AbstractStringBuilder appendNull() {
    int c = count;
    ensureCapacityInternal(c + 4);
    final char[] value = this.value;
    value[c++] = 'n';
    value[c++] = 'u';
    value[c++] = 'l';
    value[c++] = 'l';
    count = c;
    return this;
}

其中count为当前char数组容量大小;final char[] value=this.value;此处的复制是无用的,应该并不能将this.val转化为final对象,这里final修饰词最大的作用可能是提示不能将value进行重新赋值。

这里举一个例子,当ThreadA和ThreadB同时调用sb这个对象时,首先扩容ensureCapacityInternal会进行扩容由于Arrays.copyOf方法不是同步的一样会造成多线程异常

if (minimumCapacity - value.length > 0) {
    value = Arrays.copyOf(value,
            newCapacity(minimumCapacity));
}

这里扩容可能会扩大8个char或者4个char,具体原因不细讲。

然后在对value数组进行赋值,最后在执行结束时归还count,可能会有两种情况第一种是ThreadA先归还,ThreadB后归还,第二种情况是ThreadB先归还,无论谁先归还最终count都只会+4。但是由于在执行过程中ThreadA和ThreadB对value[]的赋值可能是交叉进行的,会导致append的值实际不为’null’可能为’nnuu’或者其他情况。如果出现了任意一种多线程异常状况都会导致append的值与’null’不相同,所以都应定为无效的,但是通过c来控制可以让增长的长度为恒定的4,如果不使用int c=count来控制,会使count值增长8。这里想表明的是对于多线程情况下,无论是是不是用c来临时保存count数值都不会让这个appendNull操作变得线程安全起来,但是可以保证在发生多线程不安全的情况下,浪费的空间,也就是扩容的空间最少。

2、优点

对于多线程出错降低了浪费的扩容空间

3、缺点

依旧未解决多线程错误问题

你可能感兴趣的:(JDK8源码,多线程)