Java并发(一)-了解线程安全
线程不安全性
先来举例说明线程不安全是什么情况下发生的:例如一个变量可以被多个线程进行访问,那么在大量线程并发访问这个变量的情况下,线程执行的顺序会给最后的结果带来不可预估的错误。
先定义一个单例类SimpleWorkingHardSingleton:
public class SimpleWorkingHardSingleton {
private static SimpleWorkingHardSingleton simpleSingleton = new SimpleWorkingHardSingleton();
// 数量
private int count;
private SimpleWorkingHardSingleton() {
count = 0;
}
public static SimpleWorkingHardSingleton getInstance() {
return simpleSingleton;
}
public int getCount() {
return count;
}
public void addCount(int increment) {
this.count += increment;
System.out.println(this.count);
}
}
可以看到下面这个单例若在多线程环境下运行,count是被多个线程同时操纵的变量,示例:
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
SimpleWorkingHardSingleton simpleSingleton = SimpleWorkingHardSingleton.getInstance();
simpleSingleton.addCount(1);
}
}).start();
}
看输出结果(你的执行结果可能和我的不同):
3
2
2
4
5
匪夷所思的结果,想不懂为什么会有两个2出现,1哪儿去了,为什么输出不是 1 2 3 4 5,下面就来解释一下
- 为什么没有1?
可能是a线程算出count=1,然后输出count的时候,此时a线程挂起,b线程执行,b线程对count自增,此时a线程再输出的时候,count已经发生了变化,这就导致了1没有被输出 - 为什么两个2?
可能是a,b两个线程都完成了count的计算,然后a线程输出,输出结束后立即被挂起,然后紧接着b线程立即也进行了输出,那么此时a b线程一定是输出了相同的count,就导致了相同值的出现。 - 将循环次数加大到100或者200,就会发现最后输出的count并不会到100或者200
这是由于count++这个操作也不是原子的,也就是说count++并不是一次性完成,而是分为3步骤。第一步,获取count;第二步,给count指向的值加1;第三步,讲计算结果写回count。因此如果三个步骤再混合上多线程执行顺序的错乱因素,就会导致不可预测的问题了。比如a线程获取count为1,此时a线程立马被挂起,b线程获取count也为1,然后a,b线程各自去执行,最后写回count都是2,这就导致了count被少加一次。
线程安全性
其实我们看到线程安全性的定义的关键点在于正确性,即在多线程的环境下,无论运行时候环境采用如何的调度方式,系统或者类或者方法总能表现出预期的相符的行为,那么就是线程安全的。
总结
- 在多线程环境下,之所以会出现并发的线程安全性问题,是由于多个线程去操纵一个共享的变量或者一组变量,而且变量的操作过程不是原子的,那么线程的执行顺序就会干扰到变量。
- 为了保证线程安全性,解决方法:
- 多个线程访问一个不可变量
- 变量不可以被多线程共享
- 线程做同步处理(原子性处理)
参考内容
- 书籍《Java并发编程实战》
Java并发(一)-了解线程安全的更多相关文章
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- Java并发编程:线程池的使用(转)
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java并发编程:线程控制
在上一篇文章中(Java并发编程:线程的基本状态)我们介绍了线程状态的 5 种基本状态以及线程的声明周期.这篇文章将深入讲解Java如何对线程进行状态控制,比如:如何将一个线程从一个状态转到另一个状态 ...
- Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
- (转)Java并发编程:线程池的使用
背景:线程池在面试时候经常遇到,反复出现的问题就是理解不深入,不能做到游刃有余.所以这篇博客是要深入总结线程池的使用. ThreadPoolExecutor的继承关系 线程池的原理 1.线程池状态(4 ...
- Java并发编程:线程池的使用(转载)
转载自:https://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- Java并发-UncaughtExceptionHandler捕获线程异常信息并重新启动线程
Java并发-UncaughtExceptionHandler捕获线程异常信息并重新启动线程 一.捕获异常并重新启用线程 public class Testun { public static voi ...
- Java并发编程:线程池的使用(转载)
文章出处:http://www.cnblogs.com/dolphin0520/p/3932921.html Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实 ...
- [转]Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
随机推荐
- 硬件GPIO,UART,I2C,SPI电路图
- VC6.0 OpenGL环境配置及编程基础
1.一般情况下VC并不携带glut,需要到opengl官网下载,下载地址 http://www.opengl.org/resources/libraries/glut/glut37.zip 解压后 打 ...
- 直压到亚马逊AWS平台,阿里云OSS平台或者腾讯云COS平台
GTX Compressor (直压上云技术预览版) Powered by GTXLab of Genetalks. 技术预览版本下载地址: https://github.com/Genetalks/ ...
- Part 6 - Class-Based Views(21-26)
https://github.com/sibtc/django-beginners-guide/tree/v0.6-lw urlpatterns = [ views.PostUpdateView.as ...
- flask_hello world
对于flask框架的学习全部借鉴于http://www.pythondoc.com/flask-mega-tutorial/index.html 在学习的过程中,我使用的是Pycharm IDE,Py ...
- jdk1.7和1.8共存的问题(默认1.7)
参考https://www.cnblogs.com/fxmemory/p/7234848.html 电脑上有了jdk1.7,环境变量配的是1.7,后来再安装了个1.8,结果在cmd-->java ...
- Linux各个版本资源下载
Linux系统各发行版镜像下载(持续更新) == Linux系统各发行版镜像下载(2014年10月更新),如果直接下载不了,请使用迅雷下载.并且注意,我的下载地址,在 迅雷 里才起作用. Linux ...
- nodejs中如何使用mysql数据库[node-mysql翻译]
nodejs中如何使用mysql数据库 db-mysql因为node-waf: not found已经不能使用,可以使用mysql代替. 本文主要是[node-mysql]: https://www. ...
- MOD13A1: MODIS/Terra Vegetation Indices 16-Day L3 Global 500 m SIN Grid V006
https://lpdaac.usgs.gov/node/838 Description The MOD13A1 Version 6 product provides a Vegetation Ind ...
- HDU1065 I Think I Need a Houseboat 2016-07-24 13:59 101人阅读 评论(0) 收藏
I Think I Need a Houseboat Problem Description Fred Mapper is considering purchasing some land in Lo ...