线程安全问题一定是出现在共享数据上
来源:互联网 发布:傲剑境界升级数据 编辑:程序博客网 时间:2024/06/05 06:33
共享数据的特点
1、能被所有线程访问
2、在内存中只有一份,同一时间只能被一个线程访问 ps:threadlocal主要是为了解决这个问题,使每个线程有它自己的一份数据。
3、修改对其它线程可见 ps:锁机制主要是解决这个问题,让值的改变可预测。
共享数据的可怕之处
该线程并没有执行什么代码,变量值却改变了。如果变量值的改变是不可预测的,则不是线程安全的。
给方法加锁(在该方法上属于共享数据的变量值发生改变),就是让变量值的改变可以预测。
比如一个静态变量自增10次,在多线程环境下无法预测其结果。
对自增10次这个方法加锁,就可以线程安全。
- package com;
- /**
- * @说明 变量安全测试
- * @author 崔素强
- */
- public class ThreadLocalTest {
- public static void main(String[] args) {
- Runnable accumelatora = new Accumulatort();
- Thread threada = new Thread(accumelatora, "ThreadA");
- Thread threadb = new Thread(accumelatora, "ThreadB");
- threada.start();
- threadb.start();
- }
- }
- class Accumulatort implements Runnable {
- // 静态变量
- private static int local = 0;
- @SuppressWarnings("unchecked")
- public void run() {
- // 静态变量
- for (int i = 0; i <= 10; i++) {
- local += 1;
- try {
- Thread.sleep(500);
- } catch (Exception e) {
- }
- System.out.println(Thread.currentThread().getName() + "-->"
- + local);
- }
- }
- }
运行后看控制台输出,很容就发现有时候某线程使用变量时已经被另一个线程修改了
该代码出自链接:http://cuisuqiang.iteye.com/blog/1445941
我们再来看看单例模式:
public
class
SingletonClass{
private
static
SingletonClass instance=
null
;
public
static
SingletonClass getInstance(){
if
(instance==
null
){
instance=
new
SingletonClass();
}
return
instance;
}
private
SingletonClass(){}
}
因为首先,有静态变量。
从静态变量等于null,到静态变量实例化,是一种对静态变量的修改。
它的结果是不确定的,有2种可能情况:
如果构造函数new
SingletonClass();语句的执行是一个很短暂的过程,则不会出现2个以上的线程同时进入
if
(instance==
null
)语句块,执行实例化语句的情况。
如果构造函数
new
SingletonClass();语句的执行是一个很漫长的过程,一个线程执行实例化未完成,另一个线程
就能进入
if
(instance==
null
)语句块,执行实例化语句。程序不允许创建2个一样的静态变量所以会报错。
办法:加锁
public
class
SingletonClass{
private
static
SingletonClass instance=
null
;
public
static
synchronized
SingletonClass getInstance()
{
if
(instance==
null
)
{
instance=
new
SingletonClass();
}
return
instance;
}
private
SingletonClass(){
}
}
如何改进呢?以下代码既可以保证线程安全又可以提高多线程并发的效率。
public
static
class
Singleton{
private
static
Singleton instance=
null
;
private
Singleton(){
//do something
}
public
static
Singleton getInstance(){
if
(instance==
null
){
synchronized(Singleton.
class
){
if
(
null
==instance){
instance=
new
Singleton();
}
}
}
return
instance;
}
}
- 线程安全问题一定是出现在共享数据上
- ativeperl 5.8上的线程数据共享
- Java——线程间的通信及共享数据的安全问题
- 第三章(在线程间共享数据)
- java多线程操作共享数据的安全问题
- 多线程访问共享数据的安全问题
- 浙商断言:下一个千亿市值公司,一定是出现在智能硬件领域。
- 线程安全问题出现的原因和解决方法
- java-ThreadLocal是解决线程安全问题
- APP 缓存数据线程安全问题探讨
- APP 缓存数据线程安全问题探讨
- 线程范围内共享数据
- 线程范围内数据共享
- QT线程共享数据
- 线程间共享数据
- 线程间数据共享
- 线程间数据共享
- 线程数据共享-ThreadLocal
- uoj171 bzoj 4405: [wc2016]挑战NPC 一般图最大匹配
- Uva 11426 - GCD - Extreme (II) 欧拉函数
- java中的stack
- datagrid页面获取表单一条数据的例子
- Android学习之ItemTouchHelper实现RecylerView的拖拽以及滑动删除功能
- 线程安全问题一定是出现在共享数据上
- hdu 3172(并查集+hash)
- PHP如何判断一个元素是否在已知数组中
- OpenCV学习笔记(25)基于MFC和OpenCV的摄像机定标与立体匹配测试程序(20140505更新)
- 闭包的循环引用问题
- Circumventing Group Policy Settings
- 若无心事挂枝头,便是人间好时节
- go语言学习心得
- test