这里有一个对象,最多可以由n个线程访问。我想设计一个管理类,对外提供begin和end函数,begin检查该对象是否可用,如果可用就返回该对象,如果不可用就等待。end函数释放该对象的使用权,并唤醒在begin中等待的线程。请问该如何设计?可能这个问题对于高手来说不屑一顾,但我原来一直是用C++和Win32API的,对mutex,event,semaphore这些非常熟悉。现在刚刚学习Java,上来就wait和notify,概念差别太大了,完全不能理解!还望高手帮忙解决!说句题外话,感觉还是win32API那套和经典的同步理论相符合一点,就是操作系统里讲的那套。

解决方案 »

  1.   

    单例模式+计数器(synchronized的)。
        访问前,先判断有多少个线程在使用了。访问后,计数器减操作。好像跟生产者消费者模式还不太一样。
      

  2.   


    隐藏构造函数,用类似于getInstance()方法得到引用,并计数,如果超出返回null
      

  3.   

    当前访问对象的线程数需要记录,超过n就阻塞,这个可以用ReentrantLock 
    和dr_lou一样,这个计数器是要保证线程安全的,可以用AtomicIntegerclass X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...   public void m() {
         lock.lock();  // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
     }
      

  4.   

    非常感谢楼上几位帮忙!可是我是用GAE的,只能使用java最底层的那些API,比如wait和notify,其它的包用不了啊。我想构造一个管理类,用对外提供begin和end函数,begin检查PersistenceManager对象是否可用,如果可用就返回该对象,如果不可用就等待。end函数释放PersistenceManager对象的使用权,并唤醒在begin中等待的线程。请问该如何设计?
      

  5.   

    忘了说了,就是想要处理PersistenceManager的并发访问。如果您能提供更好的办法请直说!我还没有做到Think in Java,仍然Think Java in C++,思维混乱中。
      

  6.   

    public final class Test {
    private static PersistenceManagerFactory pmf = null;
    private static PersistenceManager pm = null;
    private static Properties properties = null;
    private static int instanceCount;
    static {
    properties.setProperty("...", "...");
    pmf = JDOHelper.getPersistenceManagerFactory(properties);
    pm = pmf.getPersistenceManager();
    }

    private Test(){}

    public synchronized static PersistenceManager getPMInstance(){
    while (instanceCount != 0){
    Test.class.wait();
    }
    instanceCount = 1;
    return pm;
    }

    public synchronized static void disposePMInstance(){
    pm.close();//??????useless? 
    pm = pmf.getPersistenceManager();
    instanceCount = 0;
    Test.class.notifyAll();
    }
    }
    可能有错误,特别是close那,只是粗略看了一下他的api
    对工厂模式也不熟不知道getPersistenceManager();是不是同一个对象,如果不是应该可以
      

  7.   

    单例模式+计数器(synchronized的)。
      访问前,先判断有多少个线程在使用了。访问后,计数器减操作。好像跟生产者消费者模式还不太一样。
      

  8.   

    看看这有什么问题
    public class Test {
    private static PersistenceManager instance = new PersistenceManager();
        private static volatile int threadCounter = 0;
        // maximum concurrent threads allowed
        private static int N = 3;

    public static void rockNroll() {
    PersistenceManager instance;

    while(threadCounter >= N) {
    try {
    Thread.sleep(1000);
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    }

    if(threadCounter < N) {
    getAndAdd(1);
    System.out.println("current working threads is " + threadCounter);
    instance = doWork();
    getAndAdd(-1);
    } else {
    instance = null;
    }

    if(instance != null) {
    System.out.println("well done...");
    }

    }

    private static PersistenceManager doWork() {
    return getPMInstance();
    }

    private static synchronized void getAndAdd(int delta) {
    threadCounter += delta;
    }

        public static PersistenceManager getPMInstance() {
            return instance;
    }
        
        public static void main(String[] args) {
    for(int i = 0; i < 100; i++) {
    new Thread() {
    public void run() {
    rockNroll();
    }
    }.start();
    }
    }}class PersistenceManager {

    }