java学习|图说多线程那些孪生的线程(不)安全的类

java学习|图说多线程那些孪生的线程(不)安全的类

会飞的雨8821 2019-01-17 19:42:50

本文为多线程第一篇,

不深入细节,

大体上聊一聊我们常用的类,

先来一张图感受下:

在上面三组类中,开发时我们大都是使用的上面的,如使用StringBuilder做String拼接。 使用ArrayList存储数据库返回的一组数据, 用HashMap传参等等。

因为现在开发大都是在SpringMVC下开发,全局变量都是一些Manager, Service,Mapper之类的。 然后我们的List, Map变量一般都是在方法里面新建,使用,返回。在jvm中,局部变量存在于vm栈的每个方法的栈帧中,这个线程所私有的,不会引发线程安全问题,所以我们用上面的或是下面的程度大都可以正确的运行,也正是这样,也让我们一直没有机会深入到他们之中,看看他们有什么不一样

StringBuilder VS StringBuffer , 对比方法 append()

ArrayList VS Vector , 对比方法 add()

HashMap VS Hashtable , 对比方法 put()

细心的小伙伴们估计已经注意到了,

两个类的这些方法中,

方法名,参数,返回值,

和实现都大体上差不多,

只是在方法声明上有些差别:

synchronized.synchronized放在非static方法是,

是对当前实例加锁,

例:

Hashtable<String,String> table = new Hashtable<>();

table.put(“java”,“技术大本营”);

table.get(“java”);

我们在使用table 这个实例时,线程A要使用table的get方法,就要先等别的线程使用完put方法。这种读写相间的说是为了保证数据一致加个锁倒也无可厚非,但是,如果两个线程都是使用get方法,也是同一时间只有一个线程能读取。所以现在在项目中很少看到后Vector 和 hashtable出现了。

从日常开发中,我们不难总结出,读 其实是不需要加锁的,只有写的时候才需要加锁,而且写的时候也不至于从方法第一行就加锁,可以只对更改的那几行加锁就可以了,或者对数据分段,对需要修改的那一段数据加锁。 整体的思路就是,降低锁的粒度。 还有更厉害的就是直接不加锁了,大家一起去竞争,但改之前必须要和自己以前拿到的数据对比,中间没有人动过才能改。

相信已经有小伙伴通过上段的描述想到了对应的例子,如ConcurrentHashMap , CAS等等 , 这些是后话,今天先和大家一起认识一些孪生的线程(不)安全的类。

总结:通常一提到线程安全,大家都会第一时间想到加锁,但对谁加锁,什么时候加锁,是个值得考量的问题!

小编整理了一些java进阶学习资料和面试题,需要资料的请加JAVA高阶学习Q群:664389243 这是小编创建的java高阶学习交流群,加群一起交流学习深造。群里也有小编整理的2019年最新最全的java高阶学习资料!

猜你喜欢

转载自blog.csdn.net/weixin_44331525/article/details/86530492