1、乐观锁:假定没有冲突,在更新数据时比较发现不一致时,则读取新值修改后重试更新。(自旋锁就是一种乐观锁)
2、悲观锁:假定会发生冲突,所有操作都加上锁,比如读数据操作。
3、自旋锁:循环使用cup时间,尝试cas操作直至成功返回true,不然一直循环。(比较内存值与线程旧值是否一致,一致则更新,不然则循环)
4、共享锁(多读):给资源加上读锁,其他线程也可以加读锁,可以同时读,不可以加写锁。
5、独享锁(单写):给资源加上写锁,可以修改资源,其他线程不能再加锁。
6、可重入锁、不可重入锁:线程获取到一把锁后,可以自由进入同一把锁所同步的其他代码。
// 可重入
public class ObjectSyncDemo2 {
public synchronized void test1(Object arg) {
System.out.println(Thread.currentThread() + " 我开始执行 " + arg);
if (arg == null) {
test1(new Object());
}
System.out.println(Thread.currentThread() + " 我执行结束" + arg);
}
public static void main(String[] args) throws InterruptedException {
new ObjectSyncDemo2().test1(null);
}
}
输出:
Thread[main,5,main] 我开始执行 null
Thread[main,5,main] 我开始执行 java.lang.Object@4554617c
Thread[main,5,main] 我执行结束java.lang.Object@4554617c
Thread[main,5,main] 我执行结束null
7、公平锁、非公平锁:获取锁时,按照线程先后顺序,则公平。
8、读写锁:
// 缓存示例
public class CacheDataDemo {
// 创建一个map用于缓存
private Map<String, Object> map = new HashMap<>();
private static ReadWriteLock rwl = new reentrantreadwritelock();
public static void main(String[] args) {
// 1 读取缓存里面的数据
// cache.query()
// 2 如果换成没数据,则取数据库里面查询 database.query()
// 3 查询完成之后,数据塞到塞到缓存里面 cache.put(data)
}
public Object get(String id) {
Object value = null;
// 首先开启读锁,从缓存中去取
rwl.readLock().lock();
try {
if (map.get(id) == null) {
// Todo database.query(); 全部查询数据库 ,缓存雪崩
// 必须释放读锁
rwl.readLock().unlock();
// 如果缓存中没有释放读锁,上写锁。如果不加锁,所有请求全部去查询数据库,就崩溃了
rwl.writeLock().lock(); // 所有线程在此处等待 1000 1 999 (在同步代码里面再次检查是否缓存)
try {
// 双重检查,防止已经有线程改变了当前的值,从而出现重复处理的情况
if (map.get(id) == null) {
// Todo value = ...如果缓存没有,就去数据库里面读取
}
rwl.readLock().lock(); // 加读锁降级写锁,这样就不会有其他线程能够改这个值,保证了数据一致性
} finally {
rwl.writeLock().unlock(); // 释放写锁@
}
}
} finally {
rwl.readLock().unlock();
}
return value;
}
}
// 将hashmap改造一个并发安全的
// 比hashTable的实现,效率高,读取的适合并不会同步执行
public class MapDemo {
private final Map<String, Object> m = new HashMap<>();
private final reentrantreadwritelock rwl = new reentrantreadwritelock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public Object get(String key) {
r.lock(); // 可以同时多个线程获取这把锁
try {
return m.get(key);
} finally {
r.unlock();
}
}
public Object[] allKeys() {
r.lock();
try {
return m.keySet().toArray();
} finally {
r.unlock();
}
}
public Object put(String key, Object value) {
w.lock(); // 一个线程获取 这把锁
try {
return m.put(key, value);
} finally {
w.unlock();
}
}
public void clear() {
w.lock();
try {
m.clear();
} finally {
w.unlock();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。