请问如何在多线程环境中,使一个对象最多由n个线程访问?

fireseed 2010-07-28 09:58:10
这里有一个对象,最多可以由n个线程访问。我想设计一个管理类,对外提供begin和end函数,begin检查该对象是否可用,如果可用就返回该对象,如果不可用就等待。end函数释放该对象的使用权,并唤醒在begin中等待的线程。请问该如何设计?

可能这个问题对于高手来说不屑一顾,但我原来一直是用C++和Win32API的,对mutex,event,semaphore这些非常熟悉。现在刚刚学习Java,上来就wait和notify,概念差别太大了,完全不能理解!还望高手帮忙解决!

说句题外话,感觉还是win32API那套和经典的同步理论相符合一点,就是操作系统里讲的那套。

...全文
122 11 打赏 收藏 举报
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
yktd26 2010-07-29
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();是不是同一个对象,如果不是应该可以
  • 打赏
  • 举报
回复
colin_pxx 2010-07-29
牛人咋这么多
  • 打赏
  • 举报
回复
科學信仰 2010-07-29
看看这有什么问题


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 {

}
  • 打赏
  • 举报
回复
icy_csdn 2010-07-29
这不就是POOL设计模式么?
  • 打赏
  • 举报
回复
xianaofei 2010-07-29
单例模式+计数器(synchronized的)。
访问前,先判断有多少个线程在使用了。访问后,计数器减操作。

好像跟生产者消费者模式还不太一样。
  • 打赏
  • 举报
回复
fireseed 2010-07-28
忘了说了,就是想要处理PersistenceManager的并发访问。如果您能提供更好的办法请直说!

我还没有做到Think in Java,仍然Think Java in C++,思维混乱中。
  • 打赏
  • 举报
回复
fireseed 2010-07-28
非常感谢楼上几位帮忙!

可是我是用GAE的,只能使用java最底层的那些API,比如wait和notify,其它的包用不了啊。

我想构造一个管理类,用对外提供begin和end函数,begin检查PersistenceManager对象是否可用,如果可用就返回该对象,如果不可用就等待。end函数释放PersistenceManager对象的使用权,并唤醒在begin中等待的线程。请问该如何设计?
  • 打赏
  • 举报
回复
dr_lou 2010-07-28
[Quote=引用 3 楼 dracularking 的回复:]
当前访问对象的线程数需要记录,超过n就阻塞,这个可以用ReentrantLock
和dr_lou一样,这个计数器是要保证线程安全的,可以用AtomicInteger

class X {
private final ReentrantLock lock = new ReentrantLock();
// ...

public void m() {
lock.lo……
[/Quote]

需要恶补concurrent包了我
  • 打赏
  • 举报
回复
科學信仰 2010-07-28
当前访问对象的线程数需要记录,超过n就阻塞,这个可以用ReentrantLock
和dr_lou一样,这个计数器是要保证线程安全的,可以用AtomicInteger

class X {
private final ReentrantLock lock = new ReentrantLock();
// ...

public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}
  • 打赏
  • 举报
回复
yktd26 2010-07-28
[Quote=引用 1 楼 dr_lou 的回复:]
单例模式+计数器(synchronized的)。
访问前,先判断有多少个线程在使用了。访问后,计数器减操作。

好像跟生产者消费者模式还不太一样。
[/Quote]

隐藏构造函数,用类似于getInstance()方法得到引用,并计数,如果超出返回null
  • 打赏
  • 举报
回复
dr_lou 2010-07-28
单例模式+计数器(synchronized的)。
访问前,先判断有多少个线程在使用了。访问后,计数器减操作。

好像跟生产者消费者模式还不太一样。
  • 打赏
  • 举报
回复
发帖
Java EE
加入

6.7w+

社区成员

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
申请成为版主
帖子事件
创建了帖子
2010-07-28 09:58
社区公告
暂无公告