public class Bathroom_Lock {
private int maleAcq;
private int maleRel;
private int femaleAcq;
private int femaleRel;
private int maleWait;
private int femaleWait;
private Lock lock;
private Condition maleCondition;
private Condition lmaleCondition;
private Condition femaleCondition;
private Condition lfemaleCondition;
public Bathroom_Lock() {
lock = new ReentrantLock();
maleCondition = lock.newCondition();
lmaleCondition = lock.newCondition();
femaleCondition = lock.newCondition();
lfemaleCondition = lock.newCondition();
}
public void enterMale() {
lock.lock();
try {
++maleWait;
System.out.println("Thread " + Thread.currentThread().getName() + " waitMale");
while ((femaleWait != femaleAcq) && (maleAcq != maleRel)
|| (femaleAcq != femaleRel)) {
maleCondition.await();
}
++maleAcq;
System.out.println("Thread " + Thread.currentThread().getName() + " enterMale");
lmaleCondition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
--maleWait;
maleCondition.signalAll();
femaleCondition.signalAll();
} finally {
lock.unlock();
}
}
public void leaveMale() {
lock.lock();
try {
System.out.println("Thread " + Thread.currentThread().getName() + " toleaveMale");
if (maleRel == maleAcq){//当前bathroom没有male thread在里面,唤醒等待中的female thread
femaleCondition.signalAll();
}
while (maleRel == maleAcq) {//如果当前bathroom没有male thread在里面,current male thread进入等待状态
lmaleCondition.await();
}
++maleRel;
System.out.println("Thread " + Thread.currentThread().getName() + " leaveMale");
if (maleRel == maleAcq){//当前bathroom没有male thread在里面,唤醒等待中的female thread
femaleCondition.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
maleCondition.signalAll();
femaleCondition.signalAll();
} finally {
lock.unlock();
}
}
public void enterFemale() {
lock.lock();
try {
++femaleWait;
System.out.println("Thread " + Thread.currentThread().getName() + " waitFemale");
while ((maleWait != maleAcq) && (femaleAcq != femaleRel)
|| (maleAcq != maleRel)) {
femaleCondition.await();
}
++femaleAcq;
System.out.println("Thread " + Thread.currentThread().getName() + " enterFemale");
lfemaleCondition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
--femaleWait;
maleCondition.signalAll();
femaleCondition.signalAll();
} finally {
lock.unlock();
}
}
public void leaveFemale() {
lock.lock();
try {
System.out.println("Thread " + Thread.currentThread().getName() + " toleaveFemale");
if (femaleRel == femaleAcq){//当前bathroom没有female thread在里面,唤醒等待中的male thread
maleCondition.signalAll();
}
while (femaleRel == femaleAcq){//如果当前bathroom没有female thread在里面,current female thread进入等待状态
lfemaleCondition.await();
}
++femaleRel;
System.out.println("Thread " + Thread.currentThread().getName() + " leaveFemale");
if (femaleRel == femaleAcq){//当前bathroom没有female thread在里面,唤醒等待中的male thread
maleCondition.signalAll();
}
}catch (InterruptedException e){
e.printStackTrace();
femaleCondition.signalAll();
maleCondition.signalAll();
}finally {
lock.unlock();
}
}
}
public class Bathroom_Syn {
private int maleAcq;
private int maleRel;
private int femaleAcq;
private int femaleRel;
private int maleWait;
private int femaleWait;
public Bathroom_Syn() {
}
public synchronized void enterMale() {
try {
++maleWait;
System.out.println("Thread " + Thread.currentThread().getName() + " waitMale");
while ((femaleWait != femaleAcq) && (maleAcq != maleRel)
|| (femaleAcq != femaleRel)) {
wait();
}
++maleAcq;
System.out.println("Thread " + Thread.currentThread().getName() + " enterMale");
} catch (InterruptedException e) {
e.printStackTrace();
--maleWait;
notifyAll();
}
}
public synchronized void leaveMale() {
try {
System.out.println("Thread " + Thread.currentThread().getName() + " toleaveMale");
if (maleRel == maleAcq) {//当前bathroom没有male thread在里面,唤醒等待中的thread
notifyAll();
}
while (maleRel == maleAcq) {//如果当前bathroom没有male thread在里面,current male thread进入等待状态
wait();
}
++maleRel;
System.out.println("Thread " + Thread.currentThread().getName() + " leaveMale");
if (maleRel == maleAcq) {
notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
notifyAll();
}
}
public synchronized void enterFemale() {
try {
++femaleWait;
System.out.println("Thread " + Thread.currentThread().getName() + " waitFemale");
while ((maleWait != maleAcq) && (femaleAcq != femaleRel)
|| (maleAcq != maleRel)) {
wait();
}
++femaleAcq;
System.out.println("Thread " + Thread.currentThread().getName() + " enterFemale");
} catch (InterruptedException e) {
e.printStackTrace();
--femaleWait;
notifyAll();
}
}
public synchronized void leaveFemale() {
try {
System.out.println("Thread " + Thread.currentThread().getName() + " toleaveFemale");
if (femaleRel == femaleAcq) {//当前bathroom没有female thread在里面,唤醒等待中的male thread
notifyAll();
}
while (femaleRel == femaleAcq) {//如果当前bathroom没有female thread在里面,current female thread进入等待状态
wait();
}
++femaleRel;
System.out.println("Thread " + Thread.currentThread().getName() + " leaveFemale");
if (femaleRel == femaleAcq) {
notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
notifyAll();
}
}
}
测试示例:
public class TestBathroom {
private Bathroom_Lock bathroomSyn;
public TestBathroom(){
bathroomSyn = new Bathroom_Lock();
}
public void test(){
Thread emthr1 = new emThread();
Thread emthr2 = new emThread();
Thread lmthr1 = new lmThread();
Thread lmthr2 = new lmThread();
Thread efthr1 = new efThread();
Thread lfthr1 = new lfThread();
emthr1.start();
emthr2.start();
lmthr1.start();
lmthr2.start();
efthr1.start();
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
lfthr1.start();
}
private class emThread extends Thread{
@Override
public void run() {
bathroomSyn.enterMale();
}
}
private class lmThread extends Thread{
@Override
public void run() {
bathroomSyn.leaveMale();
}
}
private class efThread extends Thread{
@Override
public void run() {
bathroomSyn.enterFemale();
}
}
private class lfThread extends Thread{
@Override
public void run() {
bathroomSyn.leaveFemale();
}
}
}
测试结果: