美文网首页线程
记录线程安全的一点东西

记录线程安全的一点东西

作者: Answer_yzpppp | 来源:发表于2017-03-29 16:44 被阅读2次

所谓的非线程安全就是指多个线程操作同一个对象,可能会出现问题(ArrayList),而线程安全指的是多个线程操作同一个对象不会出现问题(Vector),线程安全需要用到同步机制 ,这个也导致了性能的下降非线程安全≠不安全:非线程安全指的的多个线程操作同一个对象可能会出现问题,并不是在多线程中不能使用ArrayList或者其他的非线程安全的类。只要保证在多线程中操作的不是同一个对象,就可以大胆的使用非线程安全的类。

ArrayList:如果我们创建10个线程,在每个线程中给同一个ArrayList对象添加10个元素,最后ArrayList中的总元素可能不是100个,这就是非线程安全。造成这种情况的原因是:ArrayList的add操作并没有实现同步。也就是没有保证add操作的原子性。一个 ArrayList ,在添加一个元素的时候,它可能会有两步来完成:

1. 在 Items[Size] 的位置存放此元素;

2. 增大 Size 的值。

在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而 Size=1;

而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。这样就造成了元素的缺失。

Vector:由于vector类对成员方法都加了同步锁(synchronized标志),在多线程的访问过程中,对加锁的方法同时只允许一个线程访问,也就保证了add的原子性,必须在当前线程执行完一个完整的add操作,才允许另一个线程调用add方法。

但是vector类只是相对安全,并不是绝对安全

1.

Vector test = Vector();

.......

.......

for(i =0; i < test.size(); i++)

{

/////////////////在此处当前线程时间片到期

///线程重新获取时间片,但test内元素有可能已经被其他线程修改

System.out.println(test.get(i));

}

Vector所谓的线程安全是指调用Vector类的成员方法时,其他线程不能再访问该Vector对象。但是在调用两个Vector成员方法时,当前线程有可能再完成第一个方法后时间片到期,这时其他线程可以访问该Vector对象,造成调用第二个成员方法的结果可能与预想结果不同。这时为保证线程安全,需要加synchronized。

2.要保证线程绝对安全就必需自己用synchronized把整个代码片段包起来。

synchronized(test)

{

...

}

类似的我们经常用到的场景比如:

synchronized(map){

Object value = map.get(key);

if(value ==null)

{

value =newObject();

map.put(key,value);

}

return value;

}

上面代码中 map 即使是线程安全的也没有用,如果不在外面加synchronized,map.get和map.put之间的代码片段都有可能被其他线程重入,可能出现同一个key对应多个value。

StringBuffer和StringBuilder

当两个线程同时执行sb.append()操作时,StringBuffer可以保证2个操作都被执行,不会其中一个被另一个冲掉,因为append()方法是synchronized的,这样2个append是先后执行的。但是StringBuilder则有可能发生其中一个操作被另一个冲掉的情况,因为2个线程的append()方法不需要获得锁。我觉得,所谓的线程安全,大概也就只能做到这点了,保证StringBuffer里面的方法本身不会因为同步执行而发生错误的结果。但是由于我们的应用中,如果需要控制同步,肯定不止在这个层次,否则,一般都是不需要同步的(局部变量),因此才诞生了StringBuilder类。

相关文章

  • 记录线程安全的一点东西

    所谓的非线程安全就是指多个线程操作同一个对象,可能会出现问题(ArrayList),而线程安全指的是多个线程操作同...

  • 单例设计模式笔记

    记录几种单例模式写法。 饿汉模式(线程不安全) 懒汉模式(线程不安全) 懒汉锁模式(线程安全) 懒汉双重判断模式(...

  • Java 多线程 - CAS

    前言 记录在学习线程安全知识点中,关于CAS的有关知识点。 线程安全是指:多个线程不管以何种方式访问某个类,并且在...

  • (并发三)线程安全框架,结构化并发程序

    前言:前两篇读书笔记记录了书本提及的线程安全基本理论概念,同时结合博文和实际的案例进行描述。接下来记录的是线程安全...

  • FMDB 中的多线程处理

    对于数据操作,最重要的一点就是数据安全的问题,在多线程中,线程安全是数据安全的首要前提,下面谈谈FMDB 是如何对...

  • 关于Java中的 CopyOnWriteArraySet

    最近做的课程设计中用到了Java线程安全的集合类,因此关于对Java线程安全集合类的理解做个简单记录。Java集合...

  • 2020-09-16

    2020年iOS面试 记录一下自己遇到的面试题 百度: 1.atomic是不是线程安全的?怎么保证线程安全? 2....

  • atomic是否是线程安全的?

    转自今天所看到的答案,赶紧记录下来。 首先结论是atomic是线程安全的,不是网络上流传的非线程安全。 以下是某位...

  • atomic & nonatomic

    什么是线程安全??? 线程安全:多线程操作共享数据不会出现想不到的结果就是线程安全的,否则,是线程不安全的。 at...

  • HashMap 和 Hashtable 的区别

    线程安全: HashMap 是非线程安全的,而 Hashtable 是线程安全的,因为 Hashtable 内部的...

网友评论

    本文标题:记录线程安全的一点东西

    本文链接:https://www.haomeiwen.com/subject/okzeottx.html