Fork me on GitHub

线程安全的类

常见的线程安全相关的面试题。

HashMap和Hashtable的区别

HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式。
区别1:

  • HashMap可以存放null
  • Hashtable不能存放null
    区别2:
  • HashMap不是线程安全的类
  • Hashtable是线程安全的类

StringBuffer和StringBuilder的区别

StringBuffer是线程安全的
StringBuilder是非线程安全的
所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuffer会更快些,如果是多线程,就需要用StringBuffer保证数据的安全性。

非线程安全的为什么会比线程安全的快?因为不需要同步,省略了时间。

ArrayList和Vector的区别

通过在eclipse中查看源代码可以得知:
ArrayList类的声明:

1
2
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable

Vector类的声明:

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

一模一样的~
他们的区别也在于,Vector是线程安全的类,而ArrayList是非线程安全的。

把非线程安全的集合转换为线程安全

ArrayList是非线程安全的,换句话说,多个线程可以同时进入一个ArrayList对象的add方法
借助Collections.synchronizedList,可以把ArrayList转换为线程安全的List。
与此类似的,还有HashSet, LinkedList, HashMap等等非线程安全的类,都通过工具类Collections转换为线程安全的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package multiplethread;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestThread {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = Collections.synchronizedList(list1);
}
}

线程安全的MyStack

把LinkedList通过Collections.synchronizedList转换成了一个线程安全的List。

1
List<Hero> heros = (List<Hero>) Collections.synchronizedList(new LinkedList<Hero>());

不需要在push上加synchronized修饰符
虽然多个线程可以同时进入push方法,但是调用heros.add方法的时候,同一时间,只有一个线程可以进入。

1
2
3
public void push(Hero h) {
heros.add(h);
}

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
package collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import charactor.Hero;
public class MyStack implements Stack{
//把LinkedList通过 Collections.synchronizedList转换成了一个线程安全的List
List<Hero> heros = (List<Hero>) Collections.synchronizedList(new LinkedList<Hero>());
//不需要在push上加synchronized修饰符
//虽然多个线程可以同时进入push方法,但是调用heros.add方法的时候
//同一时间,只有一个线程可以进入
public void push(Hero h) {
heros.add(h);
}
public Hero pull() {
return heros.remove(heros.size()-1);
}
public Hero peek() {
return heros.get(heros.size()-1);
}
}
Your support will encourage me to continue to create!