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. javascript中replace使用总结

    ECMAScript提供了replace()方法.这个方法接收两个参数,第一个参数可以是一个RegExp对象或者一个字符串,第二个参数可以是一个字符串或者一个函数.现在我们来详细讲解可能出现的几种情况 ...

  2. 【Electron】Electron开发入门(二):创建项目Hello Word

    创建简单的Electron程序 1.首先,切换到你的项目空间,我的在 D:\ProjectsSpace\ElectronProjects\ElectronTest,ElectronTest是案例项目文 ...

  3. 老李推荐:第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览

    老李推荐:第5章2节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 启动流程概览   每个应用都会有一个入口方法来供操作系统调用执行,Monkey这个应用的入口方法就 ...

  4. 关于WdatePicker.js的结束时间大于开始时间

    简单笔记 : WdatePicker.js 要使结束时间大于开始时间只要在线束时间的 minDate:'#F{$dp.$D(\'stimeParam\')}' 即可:不多说 详细代码如下: <t ...

  5. iOS 文件下载和打开

    最近的项目要用到一个在线报告的下载,于是完成后自己在理一下思路,大体的实现了我要得需求. 话不多说,直接上代码 首先,取到网络文件的链接,进行判段是否需求再次下载还是直接打开 #pragma mark ...

  6. contos 7/redhat 7 安装mysql

    1.给网卡配置ip.掩码.网关   2.添加dns,编辑文件:/etc/resolve.conf nameserver 202.96.209.133       //上海本地dns nameserve ...

  7. 【转载】stm32中断学习

    中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大大增加,而且中断的设置也更加 ...

  8. CF #356 div1 A. Bear and Prime 100

    题目链接:http://codeforces.com/contest/679/problem/A CF有史以来第一次出现交互式的题目,大致意思为选择2到100中某一个数字作为隐藏数,你可以询问最多20 ...

  9. 在jquery中each循环中,要用return false代替break,return true代替continue。

    在jquery中each循环中,要用return false代替break,return true代替continue. $.each(data, function (n, value) { if(v ...

  10. HashMap负载因子

    下面是HashMap的一个构造函数,两个参数initialCapacity,loadFactor 这关系HashMap的迭代性能. /** * Constructs an empty <tt&g ...