樂觀鎖(Pessimistic)與悲觀鎖(Optimistic)
阿新 • • 發佈:2018-11-05
結論
其實樂觀鎖(Optimistic)和悲觀鎖是對讀和寫而言的,悲觀鎖(Pessimistic)是讀有優勢,而樂觀鎖鎖則是寫有優勢.
所以樂觀鎖時候寫少的情況,悲觀鎖時候讀少的情況.
悲觀鎖
悲觀鎖是指在用讀取鎖鎖定一塊程式碼的時候,另一個讀取鎖依然可以進入該程式碼塊,而寫鎖不可以進入.在用寫鎖鎖定一段程式碼的時候,讀鎖和寫鎖都不能進入該程式碼塊.
樂觀鎖
樂觀鎖其實就是寫鎖優先機制,讀鎖在鎖定某一程式碼塊的時候,如果沒有寫鎖競爭,那麼就會獲得該鎖的許可權,如果進行鎖定的時候發現有寫鎖正在競爭,那麼就會丟擲例外,需要重新操作進行鎖定.競爭標誌則是
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鍾
------------------------------------*/