单例 (Singleton) 是可以同时被多个threads运用的,他们同时引用实例,调用里面的function都是可以的。但是要注意对实例变量的多线程问题。
ConcurrentHashMap 是线程安全的,它的写操作只能同时被一个线程操作,但是读操作并没有synchronize,所以如果一个线程在进行大量的put 操作时,另一个线程读取的话只是当时那一刻的内容。
Hashmap 是非线程安全的,当大量的put和delete同时进行的时候,很可能会破坏内部结构导致infinite loop。
当我们说一个Class 是thread-safe的,我们只是说他能在multi-thread的环境下保持内部结构的不被破坏,而不是在逻辑上能保持一致性。逻辑上的还得程序员自己去处理。简单的例子:
if (!map.containsKey("ABC")) { map.put("ABC", obj); // do something }
这个例子中如果两个线程同时执行 if 语句的话,就都会去 do something。但是我们其实只希望同时只能有一个线程去do something。
synchronized 在 Java 里面还能同时确保memory执行的先后顺序一致。它的锁分为Class level and Object level。如果括号里是this,instance field,又或者是synchronzied method,那是instance level。如果是static field,MyClass.class,又或者是static synchronized method,就是Class level。同一个level的锁只能同时被一个线程所有。
volatile 多用于确定multi thread情况下,每个thread获得的是最新值。因为当thread获取一个instance variable的时候,它是可以拿一个copy的,如果它不refresh这个copy,而instance variable又有变化,可能程序会出错。所以我们用volatile 告诉thread 小心了这个可能会变,所以每次读的时候都会更新。volatile同时还保证memory执行的先后顺序一致。
浙公网安备 33010602011771号