一、synchronized关键字
1、先来看一个定义,互斥锁,也叫互斥排它锁,是很多线程系统来用来实现同步的一种方式。在某一时刻,只能有一个线程可以占有这种锁,如果有多个线程试图去占有一个互斥锁时,最终只有一个线程可以成功,其他的必须等待,直到占有成功的那个线程释放锁以后,其他的线程才可以占有锁然后执行后续操作。
2、在java中,每个对象都有一个关联的锁,当一个方法被声明为synchronized的时候,执行方法的线程必须先占有到这个对象上关联的锁,然后才能执行这个方法,当方法执行结束,执行线程会释放这把锁。
3、java中的每个对象都有且只有一把锁,如果两个线程同时调用同一个对象上的声明为synchronized的方法时(可以是同一个方法或者不同的方法),只有一个线程可以执行,另一个必须等待,直到第一个线程执行完它的方法后,等待的线程才可以执行它的方法。
二、volatile关键字
1、再看一个定义,锁的范围:锁被占有和释放之间的一段时间。比如同步方法,这些方法里的锁的范围,就是执行方法所用的时间,我们称之为方法范围。我们还可以给代码块上锁,或者显示的去占有和释放一个锁,这些锁的范围是不同的,这个后面再讲。
2、java规定对基本变量的值进行读取或者保存必须是原子操作的(long和double类型变量除外)。
2、java的内存模型,可以允许线程保存变量的值到本地内存(local memory,比如机器的寄存器)。这样就产生了一个问题,一个线程更改了变量的值而另一个线程完全不知道变量的值被改变了。
解决这个问题的一个方法就是为变量定义同步的getter和setter方法,使用方法来读取和设置变量的值,这样能够成功,是因为获取一个同步锁的时候,所有在寄存器中的临时变量都会更新到主存中。
3、解决上面问题的另一个方法是使用volatile关键字,用volatile标记的变量,在每次被使用的时候都是从主存里获取的,在每次被赋值的时候,也必须更新到主存中。
Java Threads -- 数据同步(1),布布扣,bubuko.com
原文:http://www.cnblogs.com/winson/p/3611932.html