java多线程中synchronized(同步块)和volatile的区别

来源:互联网 发布:jquery.form.js教程 编辑:程序博客网 时间:2024/04/29 17:43
1、通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用

synchronized 修饰的方法 或者 代码块。

2、用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最后值。

java中多线程在内存中的存取情况:每个线程都有一个线程栈,当用到这个线程时,首先访问到栈然后有这个对象找到堆中的变量,进行提取,并进行加载。每次更改后写回到堆中,这样保证堆中数据都是最新值,其它线程用到这些共享变量是的得到的是最后值。

 下面是java中线程内存的交互:

java volatile1


可能别的线程运行完得到的变量值为2然后存到内存中,下一个线程再次加载是得到的内存中变量的值就是2了,所以得到的是最后值。

注意:volatile只能说是要改变的值n不能由他自己本身改变,例如:n++是不对的,不会起到什么作用,但是n=m++;这是可以的,这样volatile才有效,这才是原级别的。一般情况下使用关键字synchronized,进行同步,就是说同一时刻只有一个线程在执行。这样的话得到的结果就是我们想要的。

下面是一个例子:

package volatile1;/** * Created by Administrator on 2015/11/3 0003. */public class Volatile extends Thread{    //private volatile static int n=0;    private static int n=0;    public static synchronized void inc(){        n++;    }    public void run(){        for(int i=0;i<10;i++){            inc();        }    }    public static void main(String[] args) throws InterruptedException {        Thread thread[]=new Thread[100];        for(int i=0;i<thread.length;i++){            thread[i]=new Volatile();        }        for(int i=0;i<thread.length;i++){            thread[i].start();        }        for(int i=0;i<thread.length;i++){            thread[i].join();        }        System.out.println("n="+Volatile.n);    }}
运行结果是1000

而用volatile,运行结果是965,1000很多种情况,所以为保证原子性和可靠性我觉得大家还是使用synchronized比较好

0 0
原创粉丝点击