一、常见锁策略
1.乐观锁
定义
乐观锁认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正
式对数据是否产生并发冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。
执行流程
实现
Atomic*家族
AtomicInteger count = new AtomicInteger(0);//int count = 0;
count.getAndIncrement();//i++
count.incrementAndGet();//++i
System.out.println(count.getAndIncrement());
//AtomicInteger实现线程安全
private static AtomicInteger count = new AtomicInteger(0);
private static final int MAXSIZE =100000;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <MAXSIZE ; i++) {
//count++;
count.getAndIncrement();
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <MAXSIZE ; i++) {
//count--;
count.getAndDecrement();
}
}
});
t2.start();
t1.join();
t2.join();
System.out.println("最终的结果"+count);
问题
并不总是能处理所有问题,所以会引入一定的系统复杂度
问题2
Integer高速缓存问题 (-128~127)超出范围的值会重新new对象,造成结果与预期不相符。
解决方案:设置应用程序的参数(-D),设置Integer高速缓存最大值。
2.悲观锁
定义
总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,会出现并发冲突,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
例如:synchronized
问题
总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。
3.可重入锁
定义
可重入锁的字面意思是“可以重新进入的锁”,即允许同一个线程多次获取同一把锁。比如一个递归函数里有加锁操作,递归过程中这个锁会阻塞自己吗?如果不会,那么这个锁就是可重入锁(因为这个原因可重入锁也叫做递归锁)。
/**Java里只要以Reentrant开头命名的锁都是可重入锁,而且JDK提供的所有现成的Lock实现类,包括
synchronized关键字锁都是可重入的。
*/
private static Object lock = new Object();
public static void main(String[] args) {