乐观锁与悲观锁
悲观锁
悲观锁是指在用读取锁锁定一块代码的时候,另一个读取锁依然可以进入该代码块,而写锁不可以进入.在用写锁锁定一段代码的时候,读锁和写锁都不能进入该代码块.
乐观锁
乐观锁其实就是写锁优先机制,读锁在锁定某一代码块的时候,如果没有写锁竞争,那么就会获得该锁的权限,如果进行锁定的时候发现有写锁正在竞争,那么就会抛出例外,需要重新操作进行锁定.竞争标志则是
long stamp = lock.tryOptimisticRead();//有竞争返回0
lock.validate(stamp);//有竞争返回true
悲观锁示例
package Test;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main {
public static void main(String[] args) {
Pessimistic p = new Pessimistic();
Thread t1=new Thread(()->{
p.addSome();
});
Thread t2=new Thread(()->{
p.getSome();
});
Thread t3=new Thread(()->{
p.getSome();
});
t1.start();
t2.start();
t3.start();
}
}
class Pessimistic{
private ReadWriteLock lock = new ReentrantReadWriteLock();
public void addSome() {
lock.writeLock().lock();
try {
System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.writeLock().unlock();
}
}
public void getSome() {
lock.readLock().lock();
try {
System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.readLock().unlock();
}
}
}
/*-------------------------------------
结果:
addSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒
getSome方法被我锁啦,我要霸占这把锁2s钟
getSome方法被我锁啦,我要霸占这把锁2s钟
情况2:
getSome方法被我锁啦,我要霸占这把锁2s钟
getSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒
addSome方法被我锁啦,我要霸占这把锁2s钟
------------------------------------*/
乐观锁示例
package Test;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;
public class Main {
public static void main(String[] args) {
Optimistic p = new Optimistic();
Thread t1=new Thread(()->{
p.addSome();
});
Thread t2=new Thread(()->{
p.getSome();
});
Thread t3=new Thread(()->{
p.getSome();
});
t1.start();
t2.start();
t3.start();
}
}
class Pessimistic{
private ReadWriteLock lock = new ReentrantReadWriteLock();
public void addSome() {
lock.writeLock().lock();
try {
System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.writeLock().unlock();
}
}
public void getSome() {
lock.readLock().lock();
try {
System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.readLock().unlock();
}
}
}
class Optimistic{
private StampedLock lock =new StampedLock();
public void addSome() {
long stamp=lock.writeLock();
try {
System.out.println("addSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.unlockWrite(stamp);
}
}
public void getSome() {
long stamp = lock.tryOptimisticRead();//如果有其他锁,戳记会为0
try {
if(!lock.validate(stamp)) {
stamp=lock.readLock();
System.out.println("getSome方法被我锁啦,我要霸占这把锁2s钟");
Thread.sleep(2000);
}
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
try {
lock.unlockRead(stamp);
}catch (Exception e) {
// TODO: handle exception
System.out.println("已经被write锁锁了");
}
}
}
}
/*------------------------------------
结果
情况1://大多数情况
addSome方法被我锁啦,我要霸占这把锁2s钟
//间隔两秒钟
getSome方法被我锁啦,我要霸占这把锁2s钟
getSome方法被我锁啦,我要霸占这把锁2s钟
情况2:
已经被write锁锁了
addSome方法被我锁啦,我要霸占这把锁2s钟
getSome方法被我锁啦,我要霸占这把锁2s钟
------------------------------------*/