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"; // ]]> // [导读] ...
随机推荐
- bss 概念
BSS段 在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS ...
- PC-红警联机问题与下载
或许不是软件问题: 你做好相关设置了吗? 红警局域网联机的具体方法: 适用于原版红警.尤里复仇,及任何同样的扩展版. 第一步:安装IPX协议. 方法: 控制面板——网络连接(或网上邻居·属性)——本地 ...
- A Tour of Go If
The if statement looks as it does in C or Java, except that the ( ) are gone and the { } are require ...
- Asp.net Mvc 自定义Session (一),
大家都知道用系统默认的session 会存在这样的问题 如果用户过多的话 session 会自动消亡,而且不能支持分布式和集群. 这系列博客主要讲解 怎样 解决用户过多的session自动消亡,和分 ...
- kali linux 之 DNS信息收集
[dig]命令的使用: dig是linux中的域名解析工具,功能比nslookup强很多,使用也很方便. windows系统下使用dig须下载安装一下. 使用方法: root@kali:~# dig ...
- 【JavaScript】出现即使设置了ID也获取不到的可能原因与window.onload
有时候.在JavaScript中.即使设置了ID也有可能出现document.getElementById()获取不到的情况,然后你就開始想document是否写错之类的.事实上根本就不是你的代码的大 ...
- 职责链模式vs状态模式区别
状态模式在具体状态里设置了下一状态. 而职责链模式是在客户端代码里设置了下一状态的处理对象. 如果状态模式里的任何一环缺失,将导致事情无法进行下去.职责链模式的链式在客户端连接的,也就是说,如果我们请 ...
- 【转】coco2d-x 纹理研究
1.通常情况下用PVR格式的文件来进行图片显示的时候,在运行速度和内存消耗方面都要比PNG格式要快和小.一般情况下PVR消耗的内存比PNG消耗的内存小25%左右.PVR格式可以用ZWoptex导出.P ...
- Socket异步通信学习一
最近在做一个频谱管理项目,负责通信模块,自己也是小白,重头学起,直至今天通信基本框架已经完成,把自己在学习中的心得与大家分享一下,做一个socket系列的博文,顺便加固一下自己对socket通信的认识 ...
- Android开发之处理崩溃异常
众所周知,android的设备千差万别,难免会发生崩溃异常等现象,这个时候就需要捕获哪些崩溃异常了,也就是捕获崩溃异常的相关信息,并记录下来,这样一来方便开发人员和测试人员的分析与调试. 1.首先我们 ...