并发,我的理解就是同时运行多个程序。同时,难以避免的就是数据的同步问题,如果数据同步问题处理不好就很容易造成程序出现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数据同步陷阱的更多相关文章

  1. java 线程数据同步

    java 线程数据同步 由买票实例 //java线程实例 //线程数据同步 //卖票问题 //避免重复卖票 //线程 class xc1 implements Runnable{ //定义为静态,可以 ...

  2. Java多线程初学者指南(9):为什么要进行数据同步

    Java中的变量分为两类:局部变量和类变量.局部变量是指在方法内定义的变量,如在run方法中定义的变量.对于这些变量来说,并不存在线程之间共享的问题.因此,它们不需要进行数据同步.类变量是在类中定义的 ...

  3. Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解

       我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于 ...

  4. JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)

    MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...

  5. java实现高性能的数据同步

    最近在做一个银行的生产数据脱敏系统,今天写代码时遇到了一个“瓶颈”,脱敏系统需要将生产环境上Infoxmix里的数据原封不动的Copy到另一台 Oracle数据库服务器上,然后对Copy后的数据作些漂 ...

  6. Java多线程学习---------超详细总结(java 多线程 同步 数据传递 )

    目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么 ...

  7. java线程基础巩固---数据同步引入并结合jconsole,jstack以及汇编指令认识synchronized关键字

    对于多线程编程而言其实老生成谈的就是数据同步问题,接下来就会开始接触这块的东东,比较麻烦,但是也是非常重要,所以按部就班的一点点去专研它,下面开始. 数据同步引入: 这里用之前写过的银行叫号的功能做为 ...

  8. java——多线程的实现方式、三种办法解决线程赛跑、多线程数据同步(synchronized)、死锁

    多线程的实现方式:demo1.demo2 demo1:继承Thread类,重写run()方法 package thread_test; public class ThreadDemo1 extends ...

  9. 大数据实践-数据同步篇tungsten-relicator(mysql->mongo)

    // mongo)";digg_bgcolor = "#FFFFFF";digg_skin = "normal"; // ]]> // [导读] ...

随机推荐

  1. bzoj 1877 [SDOI2009]晨跑(最小费用最大流)

    Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...

  2. cs编写php字符显示问题

    1.  mysql中有mysql字符,数据库字符(各个数据库字符可不同),数据库下的表字符,表的字段字符,这些字符应保持一致具体查询命令可见网上,如不同要设置成相同才行. 2.  因为浏览器版本不同所 ...

  3. HW4.43

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  4. [读书笔记]算法(Sedgewick著)·第二章.初级排序算法

    本章开始学习排序算法 1.初级排序算法 先从选择排序和插入排序这两个简单的算法开始学习排序算法.选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序. public s ...

  5. pytho

    字符串格式化:求模操作符%可以用来将其他值转换为包含转换标志的字符串,对值进行不同方法的格式化,左右对齐,字段宽度精度,增加符号,左填充数字 字符串方法join split istitle capit ...

  6. PC-计算机动行命令里的密密!系统管理程序!

    1. gpedit.msc-----组策略 ­ 3. Nslookup-------IP地址侦测器 ­ 4. explorer-------打开资源管理器 ­ 5. logoff---------注销 ...

  7. win32键盘记录 -- 自定义窗口类

    最近学了些关于window api编程的知识,于是琢磨编写一些键盘记录器,能够把输入的按键输出到窗口内,并且实现窗口自动滚动. 封装窗口类使用了GWL_USERDATA字段来保存this指针,比较容易 ...

  8. Java条形码生成方案及二维码要点

    1.什么是条形码及其应用 条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的规则排列,用来表示一组信息的图形标识符.常见的条形码是由反射率相差很大的黑条和白条排成的平行线图案. 条形码可 ...

  9. HTML5终极备忘大全

    二.文字备忘之标签 HTML5中新增的标签 <article> 定义文章 <aside> 定义页面内容旁边的内容 <audio> 定义声音内容 <canvas ...

  10. easyui datagrid用formtater的问题

    当value是一个字符串是直接使用value会提示value没有定义,这时需要转换下value,用""+value来替换就可以了.