一道synchronized笔试题,求指点。。。

有这样一道笔试题:

使用synchronized关键字实现Semaphore接口,实现信号量同步功能。
public interface Semaphore {
void acquire(); //获取一个信号量
void release(); //释放一个信号量
}

想了许久,不知该从哪下手,似乎不是简单的定义一个类实现这个接口,重写这两个方法,加上synchronized关键字,求指点,最好有详细的代码说明,不胜感激。

需要同步的代码前面加上:mys.acquire();
后面加上:mys.release();即可。

代码如下,已经通过测试:
不加mys.acquire();和mys.release();的时候,各线程会交替输出。
加上的话,各线程会串行输出,对比执行一下就明白了。

MySemaphore.java

[code="java"]interface Semaphore {
void acquire();
void release();
}

public class MySemaphore implements Semaphore{
private StringBuffer runFlag = new StringBuffer("true");

public void acquire(){
synchronized(runFlag){
if(runFlag.toString().equals("true")){
runFlag.setLength(0);
runFlag.append("false");
}else{
try{
runFlag.wait();
runFlag.setLength(0);
runFlag.append("false");
}catch(Exception e){
e.printStackTrace();
}
}
}
}

public void release(){
synchronized(runFlag){
runFlag.setLength(0);
runFlag.append("true");
try{
runFlag.notify();
}catch(Exception e){
e.printStackTrace();
}
}
}

public static void main(String[] args){


    Runnable run = new Runnable(){
            MySemaphore mys = new MySemaphore();

            public void run(){
                mys.acquire();
                System.out.println(Thread.currentThread().getName() + " start");
                for(int j=0;j<10;j++){
                  System.out.println(Thread.currentThread().getName() + " start " + j);
                }
                System.out.println(Thread.currentThread().getName() + " end");
                mys.release();
            }
    };

    Thread t;
    for(int i=0;i<10;i++){
      t = new Thread(run);
      t.start();
    }
}

}[/code]

Semaphore 这个类在jdk的concurrent包里是有的,LZ可以看看jdk的实现,我这里随手写了一个。

public class SemaphoreImpl implements Semaphore {
private int lock = 1024;

@Override
public void acquire() throws InterruptedException {
    System.out.println(Thread.currentThread().getId() + " request lock");
    synchronized (SemaphoreImpl.class) {
        while (true) {
            if (lock == 1024) {
                System.out.println(Thread.currentThread().getId() + " I get the lock");
                lock = 1023;
                return;
            }
            SemaphoreImpl.class.wait();
        }
    }
}

@Override
public void release() {
    synchronized (SemaphoreImpl.class) {
        lock = 1024;
        SemaphoreImpl.class.notify();
        System.out.println(Thread.currentThread().getId() + " release lock");
    }
}

public static void main(String[] args) {
    final SemaphoreImpl semaphore = new SemaphoreImpl();
    Thread acquire1 = new Thread() {

        @Override
        public void run() {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    };
    acquire1.setName("acquire1");

    Thread acquire2 = new Thread() {

        @Override
        public void run() {
            try {
                semaphore.acquire();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    };
    acquire2.setName("acquire2");

    acquire1.start();
    acquire2.start();

    Thread release = new Thread() {

        @Override
        public void run() {
            semaphore.release();
        }

    };

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    release.setName("release");
    release.start();
}

}