1. 定义
不同线程通过竞争进入临界区(共享的数据和硬件资源),为了防止访问冲突,在有限的时间内只允许其中之一独占性的使用共享资源。
是Semaphore的特殊情况 当信号量的阈值设为1时就是互斥锁模式
2. 例子
Lock
package com.hqq.concurrency.mutex;
/**
* Lock
* Created by heqianqian on 2017/7/29.
*/
public interface Lock {
void acquire() throws InterruptedException;
void release();
}
Mutex
package com.hqq.concurrency.mutex;
/**
* Mutex
* 独占锁
* Created by heqianqian on 2017/7/29.
*/
public class Mutex implements Lock {
/**
* 当前锁的拥有者
*/
private Object owner;
@Override
public synchronized void acquire() throws InterruptedException {
while (owner != null) {
wait();
}
owner = Thread.currentThread();
}
@Override
public synchronized void release() {
if ( Thread.currentThread() == owner) {
owner = null;
notify();
}
}
public Object getOwner() {
return owner;
}
public void setOwner(Object owner) {
this.owner = owner;
}
}
Jar
package com.hqq.concurrency.mutex;
/**
* Jar
* Mutex锁保证jar只可以被单个Thief线程访问
* Created by heqianqian on 2017/7/29.
*/
public class Jar {
private final Lock lock;
private int beans;
public Jar(Lock lock, int beans) {
this.lock = lock;
this.beans = beans;
}
public boolean takeBean() {
boolean success = false;
try {
lock.acquire();
success = beans > 0;
if (success) {
beans -= 1;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.release();
}
return success;
}
}
Thief
package com.hqq.concurrency.mutex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Thief
* Created by heqianqian on 2017/7/29.
*/
public class Thief extends Thread {
private static Logger LOGGER = LoggerFactory.getLogger(Thief.class);
private String name;
private Jar jar;
public Thief(String name, Jar jar) {
this.name = name;
this.jar = jar;
}
/**
* 一直获取bean对象直到bean个数为0
*/
@Override
public void run() {
int beans = 0;
while (jar.takeBean()) {
beans += 1;
LOGGER.info("{} take a bean", name);
}
LOGGER.info("{} take {} beans ", name, beans);
}
}
App
package com.hqq.concurrency.mutex;
/**
* Mutex 可以防止多个线程同时访问一个资源
* 在这个例子里.我们开启两个线程Thief对象同时从jar对象中获取bean
* 一次只有一个对象可以获取bean 获得Mutex的锁 而另一个对象则将阻塞
* Created by heqianqian on 2017/7/29.
*/
public class App {
/**
* main方法
*/
public static void main(String[] args) {
Lock lock = new Mutex();
Jar jar = new Jar(lock, 2);
Thief jack = new Thief("Jack", jar);
Thief john = new Thief("Join", jar);
jack.start();
john.start();
}
}
测试结果
INFO [2017-08-09 02:08:41,674] com.hqq.concurrency.mutex.Thief: Join take a bean
INFO [2017-08-09 02:08:41,674] com.hqq.concurrency.mutex.Thief: Jack take a bean
INFO [2017-08-09 02:08:41,674] com.hqq.concurrency.mutex.Thief: Jack take 1 beans
INFO [2017-08-09 02:08:41,674] com.hqq.concurrency.mutex.Thief: Join take 1 beans