1、锁的说明
悲观锁:不支持并发操作,在一个人对账户进行修改时,会将这条记录进行上锁,其他人无法进行操作,只能一个一个地进行。
乐观锁:在一个人对账户进行修改时,此时该条记录的版本号会被修改,另外一个人再对此条记录进行修改时,其手上拿到的版本号会与数据库中的本版号进行比对,一致则可提交成功,否则失败。
表锁:在对该表格某一条记录进行修改时,会将整个表格锁定,其他人无法对该表进行操作。
行锁:在对表格中的某条记录进行操作时,会将该条记录的数据进行锁定,其他人无法对该条记录进行操作。行锁会发生死锁。
读锁:共享锁,发生死锁。
写锁:独占锁,发送死锁。
2、读写锁案例演示
不加读锁跟写锁的话会出现错误的现象。
class MyCache {
//创建HashMap
public volatile Map<String, Object> map = new HashMap<>();
//创建读写锁对象
private ReadWriteLock rwLock = new ReentrantReadWriteLock();
//写操作
public void put(String key, Object obj) {
//写锁加锁
rwLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "正在进行写操作" + key);
TimeUnit.MICROSECONDS.sleep(300);
map.put(key, obj);
System.out.println(Thread.currentThread().getName() + "写完了" + key);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放写锁
rwLock.writeLock().unlock();
}
}
//读操作
public Object get(String key) {
//读锁加锁
rwLock.readLock().lock();
Object obj = null;
try {
System.out.println(Thread.currentThread().getName() + "正在进行读操作" + key);
TimeUnit.MICROSECONDS.sleep(300);
obj = map.get(key);
System.out.println(Thread.currentThread().getName() + "读完了" + key);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放写锁
rwLock.readLock().unlock();
}
return obj;
}
}
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 1; i <= 5; i++) {
int finalI = i;
new Thread(() -> {
myCache.put(finalI + "", finalI + "");
}, String.valueOf(i)).start();
}
for (int i = 1; i <= 5; i++) {
int finalI = i;
new Thread(() -> {
System.out.println(myCache.get(finalI + ""));
}, String.valueOf(i)).start();
}
}
}
3、锁的降级-案例演示
public class LockLower {
public static void main(String[] args) {
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();//获取读锁
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();//获取写锁
//1、写锁加锁
writeLock.lock();
System.out.println("写锁降级,写的内容......");
//2、获取读锁
readLock.lock();
System.out.println("读锁读取内容");
//3、释放写锁
writeLock.unlock();
//4、释放读锁
readLock.unlock();
}
}