1.阻塞锁spa
多个线程同时调用同一个方法的时候,全部线程都被排队处理了。让线程进入阻塞状态进行等待,当得到相应的信号(唤醒,时间) 时,才能够进入线程的准备就绪状态,准备就绪状态的全部线程,经过竞争,进入运行状态。
线程
public class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){
//当其余线程进来,即处于等待阻塞状态 wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }
可是因为被调用的方法越耗时,线程越多的时候,等待的线程等待的时间也就越长,甚至于几分钟或者几十分钟。对于Web等对反应时间要求很高的系统来讲,这是不可行的,所以须要让其非阻塞,能够在没有拿到锁以后立刻返回,告诉客户稍后重试。code
2.非阻塞锁blog
多个线程同时调用一个方法的时候,当某一个线程最早获取到锁,这时其余线程判断没拿到锁,这时就直接返回,只有当最早获取到锁的线程释放,其余线程才能进来,在它释放以前其它线程都会获取失败。ip
public class Lock{ private boolean isLocked = false; public synchronized boolean lock() throws InterruptedException{ if(isLocked){
//当没有拿到锁,当即返回,线程不阻塞 return false; } isLocked = true;
return true; } public synchronized void unlock(){ isLocked = false; } }
3.自旋锁和互斥锁资源
当一个线程在获取锁的时候,若是锁已经被其它线程获取,那么该线程将循环等待,而后不断的判断锁是否可以被成功获取,直到获取到锁才会退出循环。get
获取锁的线程一直处于活跃状态,因为一直调用while循环,可是并无执行任何有效的任务,使用这种锁会形成busy-waiting。同步
互斥锁也是为了保护共享资源的同步,在任什么时候刻,最多只能有一个保持者,也就说,在任什么时候刻最多只能有一个执行单元得到锁。可是二者在调度机制上略有不一样。对于互斥锁,若是资源已经被占用,资源申请者只能进入睡眠状态。可是自旋锁不会引发调用者睡眠,若是自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁。it
//自旋锁
public class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ sout("继续不断的循环来判断是否能够拿到锁"); } isLocked = true; } public synchronized void unlock(){ isLocked = false; } }
//互斥锁
public class Lock{ private boolean isLocked = false; public synchronized void lock() throws InterruptedException{ while(isLocked){ //当其余线程进来,直接让其进入等待状态,只有当最早拿到锁的资源,才能继续执行判断是否拿到锁 wait(); } isLocked = true; } public synchronized void unlock(){ isLocked = false; notify(); } }