java数据同步陷阱
并发,我的理解就是同时运行多个程序。同时,难以避免的就是数据的同步问题,如果数据同步问题处理不好就很容易造成程序出现bug,当然,对于其造成的危害,不加详述。
首先,来看一个简单的例子,当然,这个例子也并非是我发现的。
public class StopTread {
private static boolean stopRequested;
static Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while(!stopRequested)
{
i++;
}
}
});
public static void main(String[] args) throws InterruptedException
{
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
造成这个问题的原因在于当主线程修改了stopRequested变量后,后台线程并没有及时的读取到最新的值,因此,造成了后台线程会一直运行下去。代码内容很容易理解,就是通过一个变量来控制线程的停止与运行而已。当stopRequested被主线程设置为true时,后台线程就终止运行。但是,这个程序中并没有对stopRequested做数据同步处理,这就造成了数据的不安全性,当然,并不是在所有情况都能发生这个数据的不安全性的。但至少理论上是存在,同时,我也花费了很长的时间,模拟出了这个不安全性的存在。
根据相关资料解释其原因为:
while(!stopRequested)
{
i++;
}
被优化成了:
if(!stopRequested)
while(true)
i++;
也正是由于这个优化导致了程序无法前进执行。
对于解决这个问题的方法有两种:其一是通过锁机制,其二是通过volatile修饰符。
方法一:
public class StopTread {
private static boolean stopRequested;
static Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while(!stopRequested())
{
i++;
}
}
});
private static synchronized void requestStop()
{
stopRequested = true;
}
private static synchronized boolean stopRequested()
{
return stopRequested;
}
public static void main(String[] args) throws InterruptedException
{
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
可以发现,写方法和读方法都被同步了,只同步写方法是不能实现,如果没有对读和写方法都进行同步的话,同步是不会起作用的。
方法二:
public class StopTread {
private static volatile boolean stopRequested;
static Thread backgroundThread = new Thread(new Runnable() {
public void run() {
int i = 0;
while(!stopRequested)
{
i++;
}
}
});
public static void main(String[] args) throws InterruptedException
{
backgroundThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
Volatile的修饰符不执行互斥访问,但是可以保证一个县城在读取该域的时候就讲看到最近刚刚被写入的值。
java数据同步陷阱的更多相关文章
- java 线程数据同步
java 线程数据同步 由买票实例 //java线程实例 //线程数据同步 //卖票问题 //避免重复卖票 //线程 class xc1 implements Runnable{ //定义为静态,可以 ...
- Java多线程初学者指南(9):为什么要进行数据同步
Java中的变量分为两类:局部变量和类变量.局部变量是指在方法内定义的变量,如在run方法中定义的变量.对于这些变量来说,并不存在线程之间共享的问题.因此,它们不需要进行数据同步.类变量是在类中定义的 ...
- Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解
我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于 ...
- JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...
- java实现高性能的数据同步
最近在做一个银行的生产数据脱敏系统,今天写代码时遇到了一个“瓶颈”,脱敏系统需要将生产环境上Infoxmix里的数据原封不动的Copy到另一台 Oracle数据库服务器上,然后对Copy后的数据作些漂 ...
- Java多线程学习---------超详细总结(java 多线程 同步 数据传递 )
目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么 ...
- java线程基础巩固---数据同步引入并结合jconsole,jstack以及汇编指令认识synchronized关键字
对于多线程编程而言其实老生成谈的就是数据同步问题,接下来就会开始接触这块的东东,比较麻烦,但是也是非常重要,所以按部就班的一点点去专研它,下面开始. 数据同步引入: 这里用之前写过的银行叫号的功能做为 ...
- java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁
多线程的实现方式:demo1.demo2 demo1:继承Thread类,重写run()方法 package thread_test; public class ThreadDemo1 extends ...
- 大数据实践-数据同步篇tungsten-relicator(mysql->mongo)
// mongo)";digg_bgcolor = "#FFFFFF";digg_skin = "normal"; // ]]> // [导读] ...
随机推荐
- 代码-Weka的LinearRegression类
package kit.weka; import weka.classifiers.Evaluation; import weka.classifiers.functions.LinearRegres ...
- leptonica 学习笔记1
Updated: April 26, 2015 Leptonica is a pedagogically-oriented open source site containing software t ...
- 【转】Vim 常用命令总结
使用 Vim 的时间不长,但如今已经离不开熟悉的 Vim 编辑模式了. Vim 的学习曲线是非常陡的,一开始学习的时候,面对很多的操作命令要去记住,常常望而却步. 其实,只要记住一些常用的命令,加之在 ...
- oc学习之路----QQ聊天界面
用到的技术:自定义cell,通知机制,代理模式 transform 1.自定义cell(通过代码自定义cell) ①首先新建一个类继承UITableViewCell ②重写initWithStyle: ...
- nginx 重装添加http_ssl_module模块
起因: 如果出现“[emerg] 10464#0: unknown directive "ssl" in /usr/local/nginx-0.6.32/conf/nginx.co ...
- 最新版postgresql+pgboucer安装
安装postgresql: wget https://pgbouncer.github.io/downloads/files/1.7.2/pgbouncer-1.7.2.tar.gz wget htt ...
- WebSerivce测试工具 Storm
STORM 是一款免费且开源的WebSerivce测试工具 它的功能: 1,测试任意语言测试 WebService 2,可动态调用webservice的方法,即使输入参数需要使用复杂的数据类型 3,节 ...
- 【转】Spring 4.x实现Restful web service
http://my.oschina.net/yuyidi/blog/352909 首先我们还是跟之前一样,创建一个maven项目,不过因为Spring Restful web service是基于Sp ...
- 找出数组前N大的数
这个题也是个比较有名的面试题.当然有很多变种. 题目意思基本是:从一个数据量很大的数组里找前N大的元素.不允许排序. 这个题有两个比较好的思路: 思路一:用快速排序的思想,是思想,不是要排序; 思路二 ...
- java21 封装Response:
封装Response: /** * 封装响应信息 */ public class Response { //两个常量 public static final String CRLF="\r\ ...