笔记 35 | java线程之线程安全与非线程安全
2017-11-15 16:17
267 查看
地址
线程安全与非线程安全线程安全与非线程安全
ArrayList和VectorHashMap和HashTable
StringBuilder和StringBuffer
这些有什么区别?
这些面试题常被问,答案是,左边的都是非线程安全,右边都是线程安全!
然后又问你,什么是线程安全,什么是非线程安全呢?
A.线程安全
当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B不会出错,则我们就说,该的这个A方法是线程安全的。某类的某方法是否线程安全的关键是:
(1) 该方法是否修改该类的成员变量;
(2) 是否给该方法加锁(是否用synchronized关键字修饰)。
B.非线程安全
当多个线程类并发操作某类的方法A,来修改这个A方法的某个成员变量的值B,B会出错,则我们就说,该的这个A方法是非线程安全的。synchronized
如果要把这个方法变成线程安全的,则用 synchronized关键字来修饰该方法即可:class counnt{ private int count = 0; /* * 当有多个线程类同时操作这个方法是,就容易出问题 */ public void add(){ count++; } /* * 当加了synchronized修饰后,就是线程安全的了,不过性能很低 */ public synchronized void adds(){ count++; } }
例子理解:
public Double dou(){ int a = 5; int b = 2; return new Double(a/b); }
在执行这个方法时,每一个线程都有自己的独立的栈区。当线程进入到方法执行段的时候,一个方法变量在方法代码段中被创建,并保存在线程的栈区(静态方法也放在这里)。不同线程执行这段代码时,会有不同的a/b变量。所以这里是线程安全的,因为没有数据共享。
考虑下面的例子,多线程情况下只执行一次并可以重用结果:
private Double dou; public Double dou(){ int a = 5; int b = 2; if (dou == null) { dou = new Double(a/b); } return dou; }
这个地方虽然优化了,但可惜他不是线程安全的。两个线程并发执行的时候同时进入到dou ==null这个位置,这样可能会new出一个脏的数据。
private static ThreadLocal local = new ThreadLocal(); public Double dou(){ int a = 5; int b = 2; if (local.get() == null) { local.set(new Double(a/b)); } return (Double)local.get(); }
ThreadLocal类封装了任何类型对象,并把它绑定到当前线程。线程执行dou()方法的时候,实例pi返回的是当前线程的对象。这样的调用是线程安全的。
线程安全跟非线程安全如何取舍
从第一个例子可得知,非线程的方法添加synchronized修饰就可以转化为线程安全,但是性能会相差20倍左右,如果不加的话,该类的成员变量又可能发生错误,所以具体就看你的需求,一个是否有很多线程操作这个方法,一个是否注重它的性能!相关文章推荐
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- Java线程安全与非线程安全解析
- JAVA线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- JAVA中的线程安全与非线程安全
- 拿来主义:java中的线程安全与非线程安全,以及如何使用和实现
- PHP的线程安全与非线程安全
- 【安全牛学习笔记】 安装Java、安装显卡驱动、安装网卡补丁、并发线程限制、电源优化.txt
- 2016/07/07 PHP的线程安全与非线程安全版本的区别
- Java arraylist线程不安全 vectory 线程安全
- PHP的线程安全与非线程安全版本的区别
- PHP的线程安全与非线程安全版本的区别[转帖]
- Java并发(一)-- 线程安全(从“线程不安全”说起)
- JAVA中的线程安全与非线程安全
- Java线程学习笔记之线程安全与不安全