为什么要使用线程同步:
当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用. 证了该变量的唯一性和准确性。
什么时候使用同步:
如果正在写一个变量,他可能接下来将被另一个线程读取,或者正在读取的一个上一次已经被另一个线程写过的变量,那么必须使用同步,并且,读写线程都必须用相同的监视器锁同步。
如果类中有超过一个方法在处理临界数据,必须同步所有相关的方法,如果只同步一个方法,那么其他方法将会随意的忽略这个对象锁,并可以随意调用,
1. synchronized同步:
在方法或块中加入 synchronized关键字,如:
private synchronized void save(){};
synchronized (this) {
account += money;
其他逻辑。。
}
注意:在使用并发时,将域设置成private是非常重要的,否则,synchronized关键字就不能防止其他任务直接访问域,这样就会产证冲突。
2. 使用特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
class Bank {
//需要同步的变量加上volatile
private volatile int account = 100;
public int getAccount() {
return account;
}
//这里不再需要synchronized
public void save(int money) {
account += money;
}
}