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);
 }
 
由此就可以判断出谁是线程安全的了
 
 
所谓 volatile的措施,就是
1. 每次从内存中取值,不从缓存中什么的拿值。这就保证了用 volatile修饰的共享变量,每次的更新对于其他线程都是可见的。
2. volatile保证了其他线程的立即可见性,就没有保证原子性。
3.由于有些时候对 volatile的操作,不会被保存,说明不会造成阻塞。不可用与多线程环境下的计数器
 
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
volatile只提供了保证访问该变量时,每次都是从内存中读取最新值,并不会使用寄存器缓存该值——每次都会从内存中读取。
而对该变量的修改,volatile并不提供原子性的保证。
由于及时更新,很可能导致另一线程访问最新变量值,无法跳出循环的情况
多线程下计数器必须使用锁保护。

最新文章

  1. js ---- 时间格式
  2. JSP-07-使用JavaBean封装数据
  3. C#虚方法和覆写方法
  4. 【原创】Linux下获取命令的帮助与常用命令
  5. 斜率优化(CDQ分治,Splay平衡树):BZOJ 1492: [NOI2007]货币兑换Cash
  6. Microsoft.Practices.Unity 给不同的对象注入不同的Logger
  7. OpenGL绘制简单的时钟(首发测试)
  8. poj 3630 Phone List(字典树)
  9. dreamweaver中的 map怎么调用?_制作热点图像区域
  10. php编码的一些小规范
  11. 使用redis的比较完美的加锁解锁
  12. Luogu 2018 秋令营 Test 2
  13. Could not load file or assembly &#39;Microsoft.AnalysisServices.SharePoint.Integration&#39;
  14. vue-cli 3.0 实现A-Z字母滑动选择城市列表
  15. C#学习笔记(十七):委托、事件、观察者模式、匿名委托和lambert表达式
  16. JAVA发送HttpClient请求及接收请求结果过程
  17. 修改后无警告全面支持non-ARC以及ARC的OpenUDID
  18. Java 集合-Collections工具类
  19. 2018年Android面试题含答案--适合中高级(上)
  20. Linux线程编程之生产者消费者问题【转】

热门文章

  1. Linux下实现文件共享配置[samba]
  2. 数学--数论--POJ1365——Prime Land
  3. The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
  4. 安装KubeSphere
  5. Flutter 系统是如何实现ExpansionPanelList的
  6. golang server示例
  7. springboot设置banner
  8. http协议跟tcp协议的简单理解
  9. 【Hadoop离线基础总结】Hue与Hive集成
  10. 白话马尔科夫链蒙特卡罗方法(MCMC)