首页 > 试题广场 >

以下哪些类是线程安全的()

[不定项选择题]
以下哪些类是线程安全的()
  • Vector
  • HashMap
  • ArrayList
  • StringBuffer
  • Properties
推荐
答案:ADE
A,Vector相当于一个线程安全的List
B,HashMap是非线程安全的,其对应的线程安全类是HashTable
C,Arraylist是非线程安全的,其对应的线程安全类是Vector
D,StringBuffer是线程安全的,相当于一个线程安全的StringBuilder
E,Properties实现了Map接口,是线程安全的
编辑于 2015-01-30 17:53:11 回复(37)
难道我们只能单纯的背java的那个类是线程安全的,那个类不是线程安全的么?
这和授人以鱼有何区别呢?难道就没有一种方法授人以渔?直接教我们如何去判断一个类是否是线程安全的?
java中的线程安全是什么:
就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问
什么叫线程安全:
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
看过vector源码的同学就会知道他的许多操作都是加了synchronized修饰的比如他的添加元素。(不知道synchronized是什么意思的自行百度!)
  public synchronized void addElement(E obj) {  modCount++;
        ensureCapacityHelper(elementCount + 1);  elementData[elementCount++] = obj;
 } 
而HashMap的所有操作都没有加synchronized修饰 ,不如他的put源码
public V put(K key, V value) {
     if (key == null)
         return
      putForNullKey(value);
      int hash = hash(key.hashCode());
      int i = indexFor(hash, table.length);
      for(Entry<K,V> e = table[i]; e != null; e = e.next) {
         Object k;
         if (e.hash == hash &&((k = e.key) == key || key.equals(k))) {
             V oldValue = e.value;
             e.value = value;
             e.recordAccess(this);
             return
             oldValue;    }
     }
     modCount++;
     addEntry(hash, key, value, i);
     return null;
 }
再看看ArrayList的add方法的源码
public boolean add(E e) {
     ensureCapacity(size + 1);  // Increments modCount!!
     elementData[size++] = e;
     return true;
 }
再看StringBuffer的append源码,他是有synchronized修饰的
public synchronized
  StringBuffer append(String str) {
     super.append(str);
     return this;
 }
最后是Properties的setProperty方法,他是有synchronized修饰的
public synchronized
  Object setProperty(String key, String value) {
      return
      put(key, value);
 }
由此就可以判断出谁是线程安全的了。
编辑于 2016-08-17 09:47:07 回复(77)
A:AD的说法一致
D:StringBuffer是线程安全的(同步),StringBuilder是不保证线程,(每次操作一次就是安全的)
E:Properties类是Hashtable的一个子类,hashTable是线程安全的,所以properotes是线程安全的

发表于 2015-04-23 10:08:31 回复(6)
喂  SHE
vector  stack(StringBuffer)   hashtable(properties)   enum
发表于 2018-06-26 10:24:14 回复(1)
Properties继承自HashTable, Properties中的 Store()方法把一个Properties对象的内容以一种可读的形式保存到一个文件中。Load()方法正好相反,用来读取文件,并设定Properties对象来包含keys和values。
Properties类用来方便 的读写配置文件,支持key-value形式和xml形式的配置文件,以key-value为例, Properties的load方法直接将文件读取到内存中并且以map形式来保存,用 getProperty("key")方法来取得对应的vaule值。

编辑于 2015-09-30 16:36:37 回复(0)
AE
  • ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
  • Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
  • HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。HashMap 继承AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
  • StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。StringBuffer是线程安全的。
  • Hashtable是基于陈旧的Dictionary类,完成了Map接口;HashTable的方法是同步的,而Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。此类是线程安全的:多个线程可以共享单个 Properties 对象而无需进行外部同步。

发表于 2015-01-14 21:13:25 回复(2)
properties继承hashtable,而hashtable又是线程安全的,所以properties自然也是线程安全的。
发表于 2017-02-19 10:54:18 回复(0)
ADE,Properties继承自HashTable ,而HashTable 是线程安全的
发表于 2015-02-28 14:10:05 回复(0)
完美避开所有正确答案
发表于 2017-03-07 15:34:21 回复(2)
properties继承的是hashtable,加锁实现的线程安全
发表于 2021-10-03 16:45:17 回复(0)
没用过Properties,原来它 继承了HashTable
发表于 2021-08-23 16:10:24 回复(0)
A,Vector相当于一个线程安全的List
B,HashMap是非线程安全的,其对应的线程安全类是HashTable
C,Arraylist是非线程安全的,其对应的线程安全类是Vector
D,StringBuffer是线程安全的,相当于一个线程安全的StringBuilder
E,Properties实现了Map接口,是线程安全的
发表于 2015-10-27 10:36:44 回复(0)

常用集合

图片说明

发表于 2021-02-01 18:53:13 回复(0)
做错的可能对Properties不熟悉:
  • Properties类表示一组持久的属性。Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
  • 属性列表可以包含另一个属性列表作为其“默认值”; 如果在原始属性列表中找不到属性键,则会搜索此第二个属性列表。

  • 因为Properties从继承Hashtable时,put种putAll方法可应用于Properties对象。 强烈不鼓励使用它们,因为它们允许调用者插入其键或值不是Strings。 应该使用setProperty方法。 如果store或save方法在包含非String键或值的“受损害”Properties对象上调用,则调用将失败。 类似地,如果在包含非String密钥的“受损害”Properties对象上调用propertyNames或list方法的调用将失败。

来自jdk1.8说明文档
发表于 2020-08-07 15:53:03 回复(0)
Vector相当于线程安全的list
hashMap是非线程安全的,其对应的hashtable是线程安全的
arraylist是非线程安全的,其对应的vector是线程安全的
stringbuilder是线程安全的,其对应的stringbuffer是线程安全的
properties实现了map接口,也是线程安全的
发表于 2018-10-26 22:02:10 回复(0)
线程安全概念:一个程序的安全方法对数据进行访问,操作时,其他线程不能对其进行操作。
Vector 是一个线程安全的List
HashMap非线程安全对应的线程类是HashTable。
ArrayList是非线程安全 对应的线程安全类是Vector
StringBuffer是线程安全 对应非线程安全StringBuilder
Properties实现Map接口,线程安全

Vector的源代码可以看出Vector继承自AbstractList类 实现List接口,RandomAccess接口
主要存取方法Synchronized锁保护
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{  
public synchronized boolean add(E e) { modCount++;  ensureCapacityHelper(elementCount + 1);  elementData[elementCount++] = e;  return true; }
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 E remove(int index) { modCount++;  if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index);  E oldValue = elementData(index);  int numMoved = elementCount - index - 1;  if (numMoved > 0)
 System.arraycopy(elementData, index+1, elementData, index,  numMoved);  elementData[--elementCount] = null; // Let gc do its work   return oldValue; }

}
StringBuffer 存取方法都是同步方法 不存在线程不安全情况
public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence
{
@Override public synchronized StringBuffer append(Object obj)
 {  toStringCache = null;  super.append(String.valueOf(obj));  return this; }
@Override public synchronized StringBuffer delete(int start, int end) 
{ toStringCache = null;  super.delete(start, end);  return this; }
}
StringBuilder 继承自AbstractStringBuilder 实现序列化接口 存取方法未添加同步锁
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence
{
@Override public StringBuilder append(Object obj) 
{ return append(String.valueOf(obj)); }

@Override  public StringBuilder delete(int start, int end) 
{ super.delete(start, end);  return this; }
}

编辑于 2019-01-27 17:35:52 回复(0)
可以适当记忆一些线程安全的
发表于 2018-03-31 17:59:12 回复(0)

Properties.java 部分源码 jdk1.9

    public synchronized Object setProperty(String key, String value) {
        return put(key, value);
    }

通过synchronized实现同步。

StringBuffer.java 部分源码

@Override
    public synchronized int length() {
        return count;
    }

通过synchronized实现同步

Vector.java 部分源码

@SuppressWarnings("unchecked")
    @Override
    public synchronized void sort(Comparator<? super E> c) {
        final int expectedModCount = modCount;
        Arrays.sort((E[]) elementData, 0, elementCount, c);
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        modCount++;
    }

同样通过Synchronized关键字实现同步

发表于 2018-03-12 13:54:29 回复(0)
java并发编程实战p64告诉我们如何去推断一个类或api是否是线程安全,即如果不是会带来怎么样的麻烦,占在类的设计者的角度思考,而不是使用者
发表于 2018-03-02 12:52:39 回复(0)
安全                不安全
Vector            ArrayList
HashTable      HashMap
StringBuffer   StringBuilder
Properties(用来储存属性的,以键值对的形势,线程安全)
通常一种类都会有安全和不安全的,两者会有自己的优势,不安全的快,通过一些措施可以安全。
编辑于 2017-06-16 10:37:30 回复(0)
vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。
hashtable是线程安全的,即hashtable的方法都提供了同步机制;hashmap不是线程安全的,即不提供同步机制 ;hashtable不允许插入空值,hashmap允许!
StringBuffer是线程安全,而StringBuilder是线程不安全的。
发表于 2015-03-27 14:05:21 回复(0)