package com.chzhao;

public class Volatiletest extends Thread {

    private static int count = 0;

    public void run() {
count++;
} public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Volatiletest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}

代码如上,期待输出的是10000,然后,由于count++不是线程安全的,所以输出经常会小于10000.

为了解决这个问题,增加了volatile关键字。

package com.chzhao;

public class Volatiletest extends Thread {

    private volatile static int count = 0;

    public void run() {
count++;
} public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Volatiletest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}

修改之后,还经常输出不是10000的值。

修改为synchronized形式,代码如下:

package com.chzhao;

public class SynchronizedTest extends Thread {
private static int count = 0; public void run() {
synchronized (LockClass.lock) {
count++;
}
} public static void main(String[] args) {
Thread threads[] = new Thread[10000];
for (int i = 0; i < threads.length; i++) {
threads[i] = new SynchronizedTest();
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
}
}
package com.chzhao;

public class LockClass {
public static byte[] lock = new byte[0]; }

这样修改之后,输出是10000.

这样是否说明volatile这个关键字完全没用呢?只有synchronized才能保证线程安全?

在《Java 理论与实践: 正确使用 Volatile 变量》中提到:

Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量。这两种机制的提出都是为了实现代码线程的安全性。其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错。Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。

也就是说,在某些情况下,volitile比synchronized用起来更方便,当然,同步性更差一点。

详见《Java 理论与实践: 正确使用 Volatile 变量》

参考:
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

java多线程中的volatile和synchronized的更多相关文章

  1. 彻底弄明白之java多线程中的volatile

    一. volatite 简述 Java 语言提供了一种稍弱的同步机制,即 volatile 变量.用来确保将变量的更新操作通知到其他线程,保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新. ...

  2. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  3. 多线程学习:Volatile与Synchronized的区别、什么是重排序

    java线程的内存模型 java的线程内存模型中定义了每个线程都有一份自己的共享变量副本(本地内存),里面存放自己私有的数据,其他线程不能直接访问,而一些共享变量则存在主内存中,供所有线程访问. 上图 ...

  4. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  5. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  6. Java多线程中提到的原子性和可见性、有序性

    1.原子性(Atomicity)   原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并发的情况下,就不会出 ...

  7. java 多线程中的wait方法的详解

    java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...

  8. java多线程中并发集合和同步集合有哪些?区别是什么?

    java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...

  9. JAVA多线程基础学习二:synchronized

    本篇主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题,没错就是使用synchronized. 一.如何解决线程安全问题? 一般 ...

随机推荐

  1. trackr: An AngularJS app with a Java 8 backend – Part IV 实践篇

    REST API对于前后端或后端与后端之间通讯是一个好的接口,而单页应用Single Page Applications (SPA)非常流行. 我们依然以trackr为案例,这是一个跟踪工作时间 请假 ...

  2. Ural1076(km算法)

    题目大意 给出n*n表格,第a[i,j]表示i到j的权值,现在我们要将每个a[i,j]=sum[j]-a[i,j], 求出当前二分图a[][]最小匹配 最小匹配只需将权值取负后,求二分图最大匹配,使用 ...

  3. uva12034Race

    递推,组合. 考虑第一名有i个人,则f[n]=sum(C(n,i)*f[n-i]),递推即可.. #include<cstdio> #include<algorithm> #i ...

  4. UVa 12563 Jin Ge Jin Qu hao【01背包】

    题意:给出t秒时间,n首歌分别的时间a[i],还给出一首长度为678的必须唱的劲歌金曲,问最多能够唱多少首歌(只要最后时间还剩余一秒,都可以将劲歌金曲唱完) 用dp[i]代表花费i时间时唱的歌的最大数 ...

  5. HDU 1425 sort 【哈希入门】

    题意:给出n个数,输出前m大的数 和上一题一样,将输入的数加上一个极大地值作为地址 #include<iostream> #include<cstdio> #include&l ...

  6. Html5大文件断点续传

    大文件分块   一般常用的web服务器都有对向服务器端提交数据有大小限制.超过一定大小文件服务器端将返回拒绝信息.当然,web服务器都提供了配置文件可能修改限制的大小.针对iis实现大文件的上传网上也 ...

  7. string.Format 里面包含 javascript方法参数的时候 单引号变成双引号的问题解决方法

    解决方法如下 StringBuilder sb = new StringBuilder(); var str =@"<label><input type='checkbox ...

  8. codevs 1172 Hankson 的趣味题

    woc....这题考细节处理.要注意代码的逻辑顺序还有不要作死地循环到sqrt+1. #include<iostream> #include<cstdio> #include& ...

  9. 【JS】限制两个或多个单选框最多只能选择一个

    $(function () { /*$("#checkbox1").click(function(){ if($(this).attr("checked") = ...

  10. android学习笔记五

    Android中的category大全 Api Level 3(SDK 1.5)和Api Level 4(SDK 1.6): android.intent.category.ALTERNATIVE a ...