1. 变量递增试验

     static /*volatile*/ int shared=0;//volatile也无法保证++操作的原子性
static synchronized int incrShared(){//不加synchronized的话,shared最终结果值小于预期
return ++shared;
}
public static void testIncrShared(String[] args) throws InterruptedException {
shared=0;
Thread[] thrds = new Thread[20];
for(int j=0;j<thrds.length;j++){
thrds[j] = new Thread(new Runnable() {
@Override
public void run() {
for(int k=0;k<1000;k++){
System.out.println(incrShared());
}
}
});
}
for(int j=0;j<thrds.length;j++){
thrds[j].start();
}
for(int j=0;j<thrds.length;j++){
thrds[j].join();
}
System.out.println(shared);
}

2. volatile试验

     static /*volatile*/ int a0,a1;//这里加volatile的话,可以避免r0==r1==0的结果
static /*volatile*/ int r0,r1;//这里即使加volatile,也无法避免r0==r1==0的结果
public static void testVolatile(String[] args) throws InterruptedException {
int[] a=new int[2];
int[] r=new int[2];
final int SLEEP=10;
final Object lock=new Object();
Runnable run1=new Runnable() {
@Override
public void run() {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {
e.printStackTrace();
}
//synchronized (lock) {//加锁也可以建立happens-before关系,避免r0==r1==0的结果
a0=1;
//}
r1=a1;
}
};
Runnable run2=new Runnable() {
@Override
public void run() {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e) {
e.printStackTrace();
}
//synchronized (lock) {
a1=1;
//}
r0=a0;
}
};
Thread thrd1;
Thread thrd2; int i;
int[][] acnt=new int[2][2];
int[][] rcnt=new int[2][2];
for(i=0;i<10000;i++){
a0=a1=0;
r0=r1=0;
thrd1 = new Thread(run1);
thrd2 = new Thread(run2); thrd1.start();
thrd2.start(); thrd1.join();
thrd2.join(); a[0]=a0;
a[1]=a1;
r[0]=r0;
r[1]=r1;
System.out.println(i);
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(r));
acnt[a[0]][a[1]]++;
rcnt[r[0]][r[1]]++;
}
System.out.println(Arrays.deepToString(acnt));
System.out.println(Arrays.deepToString(rcnt));
}

3. volatile试验2

     static boolean shouldStop=false;
public static void testVolatile2(String[] args) throws InterruptedException {
shouldStop=false;
Runnable run1=new Runnable() {
@Override
public void run() {
int i=0;
while (!shouldStop) {//无法读取到线程2修改后的shouldStop值,导致无限循环
i++;
//System.out.println(i);//如果调用其他函数的话,就又可以读取到shouldStop的最新值了
}
}
};
Runnable run2=new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
shouldStop=true;
}
};
Thread thrd1;
Thread thrd2; int i;
int[][] acnt=new int[2][2];
int[][] rcnt=new int[2][2];
for(i=0;i<100;i++){
thrd1 = new Thread(run1);
thrd2 = new Thread(run2); thrd1.start();
thrd2.start(); thrd2.join();
System.out.println(i);
System.out.println(shouldStop);
thrd1.join(); }
}

Java线程安全 关于原子性与volatile的试验的更多相关文章

  1. 【Java并发】1. Java线程内存模型JMM及volatile相关知识

    Java招聘知识合集:https://www.cnblogs.com/spzmmd/tag/Java招聘知识合集/ 该系列用于汇集Java招聘需要的知识点 JMM 并发编程的三大特性:可见性(vola ...

  2. Java 线程 — synchronized、volatile、锁

    线程同步基础 synchronized 和volatile是Java线程同步的基础. synchronized 将临界区的内容上锁,同一时刻只有一个进程能访问该临界区代码 使用的是内置锁,锁一个时刻只 ...

  3. 【Java线程】volatile的适用场景

    http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性 ...

  4. Java线程工作内存与主内存变量交换过程及volatile关键字理解

    Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模 ...

  5. Java线程(二):线程同步synchronized和volatile

    上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程 ...

  6. java线程之二(synchronize和volatile方法)

    要说明线程同步问题首先要说明Java线程的两个特性,可见性和有序性.多个线程之间是不能直接传递数据交互的,它们之间的交互只能通过共享变量来实现.拿上篇博文中的例子来说明,在多个线程之间共享了Count ...

  7. java线程--volatile实现可见性

    volatile关键字: 1)能够保证volatile变量的可见性 2)不能保证volatile变量复杂操作的原子性. volatile如何实现内存可见性: 深入来说:通过加入内存屏障和禁止重排序优化 ...

  8. java线程安全— synchronized和volatile

    java线程安全— synchronized和volatile package threadsafe; public class TranditionalThreadSynchronized { pu ...

  9. Java线程的概念

    1.      计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...

随机推荐

  1. Kruskal算法的实现

    #include "stdio.h" #include "stdlib.h" struct edge { int m; int n; int d; }a[]; ...

  2. 【C语言】判断三角形类型

    根据输入的三角形的三边判断三角形的类型,并输出其面积和类型. #include<stdio.h> #include<stdlib.h> #include<math.h&g ...

  3. 【转】AS3操作XML,增加、删除、修改

    var i:Number=0;//用于下面循环 var webcontent:String="Sontin's Blog <b>Welcome to 终吾一生</b> ...

  4. 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

    老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程   poptest是国内唯一一家培养测试开发工程师的培训机 ...

  5. 性能调优之MYSQL高并发优化下

    三.算法的优化 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写..使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效 ...

  6. mysql笔记一——安装和设置root密码

    1. mysql 5.6安装包下载. MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果是msi格式的可以直接点击安装,按照它给出的安装提示进行安装(相信大家的英文可以看懂英文提 ...

  7. mac下CSV文件用FileReader、FileWriter读写乱码

      先说下windows的excel文件搬到mac下打开为什么会显示乱码.    在win下,excel采用GBK编码,1个汉字是存为2个字节,而mac下各种软件广泛默认使用UTF-8编码方式,如在e ...

  8. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  9. 一个只有99行代码的JS流程框架

    张镇圳,腾讯Web前端高级工程师,对内部系统前端建设有多年经验,喜欢钻研捣鼓各种前端组件和框架. 最近一直在想一个问题,如何能让js代码写起来更语义化和更具有可读性. 上周末的时候突发奇想,当代码在运 ...

  10. 关于binary log一点总结[转]

    阅读目录(Content) 1 what's binary log 2 Binary Logging Options and Variables 2.1 基础参数 3 Binary Logging F ...