1、
通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,
同一时刻只能有一个线程
能够用
synchronized 修饰的方法 或者 代码块。
2、用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最后值。
java中多线程在内存中的存取情况:每个线程都有一个线程栈,当用到这个线程时,首先访问到栈然后有这个对象找到堆中的变量,进行提取,并进行加载。每次更改后写回到堆中,这样保证堆中数据都是最新值,其它线程用到这些共享变量是的得到的是最后值。
下面是java中线程内存的交互:
可能别的线程运行完得到的变量值为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比较好