zoukankan      html  css  js  c++  java
  • java中的线程安全

    难道我们只能单纯的背java的那个类是线程安全的,那个类不是线程安全的么?
    这和授人以鱼有何区别呢?难道就没有一种方法授人以渔?直接教我们如何去判断一个类是否是线程安全的?
    java中的线程安全是什么:
    就是线程同步的意思,就是当一个程序对一个线程安全的方法或者语句进行访问的时候,其他的不能再对他进行操作了,必须等到这次访问结束以后才能对这个线程安全的方法进行访问
    什么叫线程安全:
    如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 
    或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
    线程安全问题都是由全局变量及静态变量引起的。
    若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
    看过vector源码的同学就会知道他的许多操作都是加了synchronized修饰的比如他的添加元素。(不知道synchronized是什么意思的自行百度!)

    1
    2
    3
    public synchronized void addElement(E obj) {  modCount++;
           ensureCapacityHelper(elementCount + 1);  elementData[elementCount++] = obj;
    }

    而HashMap的所有操作都没有加synchronized修饰 ,不如他的put源码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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方法的源码

    1
    2
    3
    4
    5
    public boolean add(E e) {
         ensureCapacity(size + 1);  // Increments modCount!!
         elementData[size++] = e;
         return true;
     }

    再看StringBuffer的append源码,他是有synchronized修饰的

    1
    2
    3
    4
    5
    public synchronized
      StringBuffer append(String str) {
         super.append(str);
         return this;
     }

    最后是Properties的setProperty方法,他是有synchronized修饰的

    1
    2
    3
    4
    5
    public synchronized
      Object setProperty(String key, String value) {
          return
          put(key, value);
     }

    由此就可以判断出谁是线程安全的了。

  • 相关阅读:
    通过命令行指定 Java 程序运行时使用的字符集
    Ubuntu Linux 开启 root 用户及其它登录问题的解决
    SLF4J 的几种实际应用模式 SLF4J+Log4J 与 SLF4J+LogBack
    Java 获取当前时间的年月日方法
    Eclipse 全屏插件
    Linux 下的纯 C 日志函数库: zlog
    如何使用 Log4j
    DAO 设计模式
    为什么要用 /dev/null 2>&1 这样的写法
    NSDate和NSString之间的转换
  • 原文地址:https://www.cnblogs.com/Yoxshen/p/9005114.html
Copyright © 2011-2022 走看看