java多线程系列七之线程安全的集合类

java多线程系列七之线程安全的集合类_第1张图片

java多线程系列七之线程安全的集合类_第2张图片

 


1. Hashtable  
 
Hashtable和HashMap一样,Hashtable也是一个散列表,它存储的内容是键值对(key-value)映射
1
2
3
4
5
6
7
8
Class Hashtable
继承的类
java.lang.Object 
java.util.Dictionary 
java.util.Hashtable 
实现的接口
All Implemented Interfaces: 
Serializable, Cloneable, Map 

 java多线程系列七之线程安全的集合类_第3张图片

构造函数

    • Hashtable()

      Constructs a new, empty hashtable with a default initial capacity (11) and load factor (0.75).

      构造一个新的,空的哈希表,该实例带有默认的初始容量11 和默认的加载因子0.75

      Hashtable(int initialCapacity)

      Constructs a new, empty hashtable with the specified initial capacity and default load factor (0.75).

      构造一个新的,空的哈希表,该实例带有指定的的初始容量和默认的加载因子0.75

      Hashtable(int initialCapacity, float loadFactor)

      Constructs a new, empty hashtable with the specified initial capacity and the specified load factor.

      构造一个新的,空的h哈希表,该实例带有指定的的初始容量和指定的加载因子0.75

      Hashtable(Map t)

      Constructs a new hashtable with the same mappings as the given Map.

      构造一个新的哈希表,该实例带有与给定的Map相同的映射

 那么Hashtable是如何保证线程安全性的呢,看下源码。

java多线程系列七之线程安全的集合类_第4张图片

Hashtable对外主要接口

java多线程系列七之线程安全的集合类_第5张图片

java多线程系列七之线程安全的集合类_第6张图片

Hashtable实现的Cloneable接口,即实现了clone()方法。clone()方法的作用很简单,就是克隆一个Hashtable对象并返回

 Hashtable实现的Serializable接口分别实现了串行读取,写入功能。

Hashtable使用实例如下

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.util.Hashtable;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
class TestB {
	public static void main(String[] args){
		Hashtable numbers=new Hashtable<>();
		numbers.put("one",1);
		numbers.put("two",2);
		numbers.put("three",3);
		Integer n=numbers.get("one");
		if (n!=null) {
			System.out.println("two ="+n);
		}
		Set key=numbers.keySet();//无序的集合
		for(String str:key){
			System.out.println(str);
		}

		Set> entry=numbers.entrySet();
		for (Map.Entry entryset:entry) {
			System.out.println(entryset.getKey()+":"+entryset.getValue());
		}
      
      Iterator> it=numbers.entrySet().iterator();
      while(it.hasNext()){
      	Map.Entry entry1=it.next();
      	String key_=entry1.getKey();
      	Integer value_=entry1.getValue();
      	System.out.println(key_+":"+value_);
      }

       System.out.println("分割线");
      Hashtable clone=(Hashtable)numbers.clone();//浅复制,与numbers的内存空间不一样
      clone.put("one",11);//后面出现提示 -Xlint:unchecked的原因,想想为什么
      Set> entrytwo=clone.entrySet();
		for (Map.Entry entrysettwo:entrytwo) {
			System.out.println(entrysettwo.getKey()+":"+entrysettwo.getValue());
		}
    
        numbers.clear();
        clone.clear();
	}
}

 java多线程系列七之线程安全的集合类_第7张图片

详细参考  https://www.cnblogs.com/williamjie/p/9099141.html

 2.java.util.concurrent.ConcurrentHashMap

Class ConcurrentHashMap

//继承的父类

  • java.lang.Object
    • java.util.AbstractMap
      • java.util.concurrent.ConcurrentHashMap
  • Type Parameters:

    K - the type of keys maintained by this map

    V - the type of mapped values

    All Implemented Interfaces:实现的接口

    Serializable, ConcurrentMap, Map

java多线程系列七之线程安全的集合类_第8张图片

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class ConcurrentHashMap extends AbstractMap
    implements ConcurrentMap, Serializable {

.......

   static class Segment extends ReentrantLock implements Serializable {
        private static final long serialVersionUID = 2249069246763182397L;
        final float loadFactor;
        Segment(float lf) { this.loadFactor = lf; }
    }

} 

ConcurrentHashMap常用的主要对外接口

    • void clear()

      Removes all of the mappings from this map.

 

    • boolean contains(Object value)

      Legacy method testing if some key maps into the specified value in this table.

      boolean containsKey(Object key)

      Tests if the specified object is a key in this table.

    • Enumeration elements()

      Returns an enumeration of the values in this table.

 

    • Set> entrySet()

      Returns a Set view of the mappings contained in this map.

    • V get(Object key)

      Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

 

    • V put(K key, V value)

      Maps the specified key to the specified value in this table.

      void putAll(Map m)

      Copies all of the mappings from the specified map to this one.

    • V remove(Object key)

      Removes the key (and its corresponding value) from this map.

      boolean remove(Object key, Object value)

      Removes the entry for a key only if currently mapped to a given value.

 

    • void forEach(long parallelismThreshold, BiConsumer action)

      Performs the given action for each (key, value).

      针对每个键值对执行给定的行为

       void forEach(long parallelismThreshold, BiFunction transformer, Consumer action)

      Performs the given action for each non-null transformation of each (key, value).

java多线程系列七之线程安全的集合类_第9张图片 ConcurrentHashMap使用实例如下

 

import java.util.Hashtable;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Enumeration;
class TestB {
    public static void main(String[] args){
    ConcurrentHashMap map=new ConcurrentHashMap<>();
    map.put("one",1);
    map.put("two",2);
    map.put("three",3);
    map.put("four",4);
System.out.println(map.get("four"));
    Set str=map.keySet();
    for(String s:str){
        System.out.println(s);
    }
    Enumeration num=map.elements();
    
    while(num.hasMoreElements()){
        Integer value = (Integer)num.nextElement();
        System.out.println(value);
    }
    
    if (map.containsKey("one")&&map.get("one").equals(1)){
        map.remove("one");
    }
    Set> et=map.entrySet();
    for(Map.Entry se:et){
        System.out.println(se.getKey()+":"+se.getValue());
    }
    map.forEach((k,v)->{
        if(k instanceof String)
            System.out.println(v);
    });
    map.forEach(3,(k,v)->{
        if(k instanceof String)
            System.out.println(v);
    });
}
}

java多线程系列七之线程安全的集合类_第10张图片

具体请参考  https://www.cnblogs.com/williamjie/p/9099861.html

ConcurrentHashMap是并发效率更高的Map,用来替换其他线程安全的Map容器,比如Hashtable和Collections.synchronizedMap。 

 

3.java.util.concurrent.CopyOnWriteArrayList

Class CopyOnWriteArrayList

父类

  • java.lang.Object
    • java.util.concurrent.CopyOnWriteArrayList
  • Type Parameters:

    E - the type of elements held in this collection

    All Implemented Interfaces:  实现的接口

  • Serializable, Cloneable, Iterable, Collection, List, RandomAccess

java多线程系列七之线程安全的集合类_第11张图片

看一下它的部分源码,其中的一个add方法的实现

 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class CopyOnWriteArrayList
    implements List, RandomAccess, Cloneable, java.io.Serializable {

 final transient ReentrantLock lock = new ReentrantLock();

    /** The array, accessed only via getArray/setArray. */
    private transient volatile Object[] array;
    	  public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
      @SuppressWarnings("unchecked")
    private E get(Object[] a, int index) {
        return (E) a[index];
    }
}

 主要方法如下

 

java多线程系列七之线程安全的集合类_第12张图片

    • boolean add(E e)

      Appends the specified element to the end of this list.

      void add(int index, E element)

      Inserts the specified element at the specified position in this list.

      boolean addAll(Collection c)

      Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's iterator.

      boolean addAll(int index, Collection c)

      Inserts all of the elements in the specified collection into this list, starting at the specified position.

      int addAllAbsent(Collection c)

      Appends all of the elements in the specified collection that are not already contained in this list, to the end of this list, in the order that they are returned by the specified collection's iterator.

      boolean addIfAbsent(E e)

      Appends the element, if not present.

      void clear()

      Removes all of the elements from this list.

      Object clone()

      Returns a shallow copy of this list.

      boolean contains(Object o)

      Returns true if this list contains the specified element.

      boolean containsAll(Collection c)

      Returns true if this list contains all of the elements of the specified collection.

      boolean equals(Object o)

      Compares the specified object with this list for equality.

      void forEach(Consumer action)

      Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.

      E get(int index)

      Returns the element at the specified position in this list.

      int hashCode()

      Returns the hash code value for this list.

      int indexOf(E e, int index)

      Returns the index of the first occurrence of the specified element in this list, searching forwards from index, or returns -1 if the element is not found.

      int indexOf(Object o)

      Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.

      boolean isEmpty()

      Returns true if this list contains no elements.

      Iterator iterator()

      Returns an iterator over the elements in this list in proper sequence.

      int lastIndexOf(E e, int index)

      Returns the index of the last occurrence of the specified element in this list, searching backwards from index, or returns -1 if the element is not found.

      int lastIndexOf(Object o)

      Returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element.

      ListIterator listIterator()

      Returns a list iterator over the elements in this list (in proper sequence).

      ListIterator listIterator(int index)

      Returns a list iterator over the elements in this list (in proper sequence), starting at the specified position in the list.

      E remove(int index)

      Removes the element at the specified position in this list.

      boolean remove(Object o)

      Removes the first occurrence of the specified element from this list, if it is present.

      boolean removeAll(Collection c)

      Removes from this list all of its elements that are contained in the specified collection.

      boolean removeIf(Predicate filter)

      Removes all of the elements of this collection that satisfy the given predicate.

      void replaceAll(UnaryOperator operator)

      Replaces each element of this list with the result of applying the operator to that element.

      boolean retainAll(Collection c)

      Retains only the elements in this list that are contained in the specified collection.

      E set(int index, E element)

      Replaces the element at the specified position in this list with the specified element.

      int size()

      Returns the number of elements in this list.

      void sort(Comparator c)

      Sorts this list using the supplied Comparator to compare elements.

      Spliterator spliterator()

      Returns a Spliterator over the elements in this list.

      List subList(int fromIndex, int toIndex)

      Returns a view of the portion of this list between fromIndex, inclusive, and toIndex, exclusive.

      Object[] toArray()

      Returns an array containing all of the elements in this list in proper sequence (from first to last element).

       T[] toArray(T[] a)

      Returns an array containing all of the elements in this list in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array.

      String toString()

      Returns a string representation of this list.

 CopyOnWriteArrayList的简单使用示例如下

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Hashtable;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Enumeration;
class TestB {
	public static void main(String[] args){
		CopyOnWriteArrayList list=new CopyOnWriteArrayList<>();
		list.add("one");
		list.add("two");
		list.add("three");
		System.out.println(list.get(1));
		if (list.contains("three")) {
			Iterator value=list.iterator();
			while(value.hasNext()){
				System.out.println(value.next());
			}
		}

}
}
 

 

java多线程系列七之线程安全的集合类_第13张图片

详细参考  https://www.cnblogs.com/clarino/p/12804072.html

4.java.util.concurrent.CopyOnWriteArraySet

Class CopyOnWriteArraySet

  • java.lang.Object
    • java.util.AbstractCollection
      • java.util.AbstractSet
        • java.util.concurrent.CopyOnWriteArraySet
  • Type Parameters:

    E - the type of elements held in this collection

    All Implemented Interfaces:

    Serializable, Iterable, Collection, Set

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class CopyOnWriteArraySet extends AbstractSet
        implements java.io.Serializable {
        	  private final CopyOnWriteArrayList al;

    /**
     * Creates an empty set.
     */
    public CopyOnWriteArraySet() {
        al = new CopyOnWriteArrayList();
    }
     public void clear() {
        al.clear();
    }
      public boolean remove(Object o) {
        return al.remove(o);
    }
      public boolean add(E e) {
        return al.addIfAbsent(e);
    }
    public boolean containsAll(Collection c) {
        return al.containsAll(c);
    }
    ...
    大多数方法皆如此
}

 java多线程系列七之线程安全的集合类_第14张图片

简单使用如下

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Hashtable;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.Enumeration;
class TestB {
	public static void main(String[] args){
		CopyOnWriteArraySet list=new CopyOnWriteArraySet<>();
		list.add("one");
		list.add("two");
		list.add("three");
		
		if (list.contains("three")) {
			Iterator value=list.iterator();
			while(value.hasNext()){
				System.out.println(value.next());
			}
		}

}
}

 运行结果

java多线程系列七之线程安全的集合类_第15张图片

Java里面List和Set的相同和区别同样适用于CopyOnWriteArrayList和CopyOnWriteArraySet,不同之处是后两者是线程安全机制 

 

CopyOnWrite机制介绍
CopyOnWrite容器是 写时复制的容器,就是我们往容器里写东西时,不是直接写,而是先Copy当前容器,然后往新容器里添加元素,在将原容器的引用指向新容器。这样做的好处是:可以并发的读,而不需要加锁,因为当前容器不会添加任何元素。CopyOnWrite容器是一种读写分离的思想。
应用场景:应用于读多写少的并发场景,
注意:减少扩容开销;使用批量添加(减少复制次数);
缺点:内存占用问题;数据一致性问题(CopyOnWrite机制只能保证最终的数据一致,不能保证实时数据一致,因此如果希望写入的数据能马上读到,就不应该用CopyOnWrite);

java多线程系列七之线程安全的集合类_第16张图片

5.java.util.Vector

构造函数

    • Vector()

      Constructs an empty vector so that its internal data array has size 10 and its standard capacity increment is zero.

      构造空的Vector,该Vector内部数组大小默认为0,标准容量增量为0

      Vector(Collection c)

      Constructs a vector containing the elements of the specified collection, in the order they are returned by the collection's iterator.

      构造包含指定的集合的元素的Vector,按集合的迭代器返回它们的顺序。

      Vector(int initialCapacity)

      Constructs an empty vector with the specified initial capacity and with its capacity increment equal to zero.

      构造一个空的带有给定容量的Vector,默认容量增量0

      Vector(int initialCapacity, int capacityIncrement)

      Constructs an empty vector with the specified initial capacity and capacity increment.

      构造带有给定容量和容量增量的vector

 

Vector是矢量队列,通过数组保存数据,它继承于AbstractList实现了List,RandomAccess,Cloneable这些接口

 

1
2
3
public class Vector
    extends AbstractList
    implements List, RandomAccess, Cloneable, java.io.Serializable

Vector继承了AbstractList,实现List;所以他是一个队列,支持相关的添加,删除,修改,遍历等功能。

Vector实现了RandomAccess接口,即提供了随机访问功能。RandomAccess是Java中用来被List实现,为List提供快速访问功能的,在Vector中,可以通过元素的序号快速获取元素对象,这就是快速随机访问。

Vecotr实现了Cloneable接口,即实现clone()函数,它能被克隆。

和ArrayList不同,Vector中的操作是线程安全的,他是利用synchronized同步显示锁的方法锁的机制实现,实现安全机制类似Hashtable.

夏眠看一下Vector的源码,注意方法锁:

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public class Vector
    extends AbstractList
    implements List, RandomAccess, Cloneable, java.io.Serializable
{
   
    protected Object[] elementData;
        public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }


    public synchronized void removeAllElements() {
        modCount++;
        // Let gc do its work
        for (int i = 0; i < elementCount; i++)
            elementData[i] = null;

        elementCount = 0;
    }

   
    public synchronized Object clone() {
        try {
            @SuppressWarnings("unchecked")
                Vector v = (Vector) super.clone();
            v.elementData = Arrays.copyOf(elementData, elementCount);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }


    public synchronized Object[] toArray() {
        return Arrays.copyOf(elementData, elementCount);
    }


    @SuppressWarnings("unchecked")
    public synchronized  T[] toArray(T[] a) {
        if (a.length < elementCount)
            return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());

        System.arraycopy(elementData, 0, a, 0, elementCount);

        if (a.length > elementCount)
            a[elementCount] = null;

        return a;
    }


    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }


    public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }


    public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }


    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    .......
}

 上面是Vector提供得几个主要方法,包括addElement(),removeElement(),get()等。注意到每个方法本身都是加了synchronized修饰的,不会出现两个线程同时对数据进行操作的情况,因此保证了线程安全性。

    • void addElement(E obj)

      Adds the specified component to the end of this vector, increasing its size by one.

      添加指定的组件到Vector的尾部,它的大小增加一

    • void clear()

      Removes all of the elements from this Vector.

      从该Vector中删除所有的元素

    • Object clone()

      Returns a clone of this vector.

      返回该Vector的克隆

 

    • boolean contains(Object o)

      Returns true if this vector contains the specified element.

      如果该Vector中包含指定的元素,返回true

    • E firstElement()

      Returns the first component (the item at index 0) of this vector.

      返回该Vector中第一个组件(索引为0的项)

 

    • int indexOf(Object o)

      Returns the index of the first occurrence of the specified element in this vector, or -1 if this vector does not contain the element.

      返回指定的元素在Vector第一次出现的索引,如果没有该元素,则返回-1

 

    • boolean isEmpty()

      Tests if this vector has no components.

      检查该Vector是否包含元素(组件)

    • Iterator iterator()

      Returns an iterator over the elements in this list in proper sequence.

      以正确的序列返回遍历列表的元素的迭代器

 

    • E lastElement()

      Returns the last component of the vector.

      返回该Vector种最后一个组件(元素)

    • boolean removeElement(Object obj)

      Removes the first (lowest-indexed) occurrence of the argument from this vector.

      删除第一次出现在该Vetor中的指定组件(最小索引)

 

    •  T[] toArray(T[] a)

      Returns an array containing all of the elements in this Vector in the correct order; the runtime type of the returned array is that of the specified array.

      返回一个包含以正确顺序出现在Vector中元素的数组,该运行时返回的数组是一个特定的数组

下面是Vector的简单使用实例

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.util.Vector;
import java.util.Iterator;
class TestB {

	public static void main(String[] args){

Vector list=new Vector<>();
list.addElement("one");
list.addElement("two");
list.addElement("three");
System.out.println(list);
for (String str:list) {
	System.out.println(str);
	
}
if(list.contains("one")){
	Iterator value=list.iterator();
	while (value.hasNext()) {
System.out.println(value.next());		
	}
}
System.out.println("分割线");
System.out.println(list.firstElement());
list.removeElement("two");
System.out.println(list);

}
}

 java多线程系列七之线程安全的集合类_第17张图片

Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能。

向量和数组相似,都可以保存一组数据(数据列表)。但是数组的大小是固定的,一旦指定,就不能改变,而向量却提供了一种类似于“动态数组”的功能,向量与数组的重要区别之一就是向量的容量是可变的。

可以在向量的任意位置插入不同类型的对象,无需考虑对象的类型,也无需考虑向量的容量。

向量和数组分别适用于不同的场合,一般来说,下列场合更适合于使用向量:
如果需要频繁进行对象的插入和删除工作,或者因为需要处理的对象数目不定。
列表成员全部都是对象,或者可以方便的用对象表示。
需要很快确定列表内是否存在某一特定对象,并且希望很快了解到对象的存放位置。

向量作为一种对象提供了比数组更多的方法,但需要注意的是,向量只能存储对象,不能直接存储简单数据类型,因此下列场合适用于使用数组:
所需处理的对象数目大致可以确定。
所需处理的是简单数据类型。

 6.常用的StringBuffer与StringBuilder

在编写JAVA代码的过程中有时要频繁地对字符串进行拼接,如果直接用“+”拼接的话会建立很多的String型对象,严重的话会对服务器资源和性能造成不小的影响;而使用StringBuilder和StringBuffer能解决以上问题。而StringBuffer是线程安全的,StringBuidler不是线程安全的。

来看下StringBuffer的一些源码:

    • StringBuffer()

      Constructs a string buffer with no characters in it and an initial capacity of 16 characters.

      StringBuffer(CharSequence seq)

      Constructs a string buffer that contains the same characters as the specified CharSequence.

      StringBuffer(int capacity)

      Constructs a string buffer with no characters in it and the specified initial capacity.

      StringBuffer(String str)

      Constructs a string buffer initialized to the contents of the specified string.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    /**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    static final long serialVersionUID = 3388685877147921107L;
     @Override
    public synchronized StringBuffer append(Object obj) {
        toStringCache = null;
        super.append(String.valueOf(obj));
        return this;
    }

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
      public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }

    /**
     * @since 1.8
     */
    @Override
    synchronized StringBuffer append(AbstractStringBuilder asb) {
        toStringCache = null;
        super.append(asb);
        return this;
    }
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
    ......
}

 

而StringBuilder的部分源码如下

    • StringBuilder()

      Constructs a string builder with no characters in it and an initial capacity of 16 characters.

      StringBuilder(CharSequence seq)

      Constructs a string builder that contains the same characters as the specified CharSequence.

      StringBuilder(int capacity)

      Constructs a string builder with no characters in it and an initial capacity specified by the capacity argument.

      StringBuilder(String str)

      Constructs a string builder initialized to the contents of the specified string.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
	    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
     @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }
    ......
}

 

不难看出在高并发的情况下,如果不需要考虑数据安全问题的情况下,尽量使用StringBuffer,由于没有资源等待的情况,肯定执行效率和性能会高很多。所以是使用StringBuffer还是使用StringBuilder要视情况而定。

 

下面对线程安全做个小结:

在掌握线程的安全原理和锁的机制的情况下再去理解和查看java里面所提供的线程的安全类,我们就知道怎么回事了。

最后关于执行效率总结一句:有关代码执行效率,没有加锁的,不需要同步安全的代码执行效率最高>方法块锁>类锁和方法锁,同时要注意读写分离的业务场景。

你可能感兴趣的:(java多线程系列七之线程安全的集合类)