只允许两个线程对一个函数进行操作

时间:2010-09-14 13:14:44

标签: java multithreading

我有一个不寻常的问题。 我有一个函数,这个函数的操作一次可以由两个线程完成。

static int iCount = 1;
public synchronized void myFunct(){ 
while(iCount >= 3)
{
   try {
       wait();
   } catch (InterruptedException e) {
       e.printStackTrace();
 }

 iCount++; 

 //Do Stuffs
 //After operation decrement count

 iCount --;
 notifyAll();
}

我想要做的是,我想只允许两个线程做一些操作,其他线程必须等待。

但是这里前两个线程递增计数并执行操作,其他线程进入等待状态但是没有得到通知。

我想我忽略了一些事情。

7 个答案:

答案 0 :(得分:11)

听起来您想要使用Semaphore,在执行操作之前总是调用acquire(),然后在finally块中调用release()

private static final Semphore semaphore = new Semaphore(2);

public static void myFunct() throws InterruptedException {
    semaphore.aquire();
    try {
        // do stuff
    } finally {
        semaphore.release();
    }
}

答案 1 :(得分:2)

您的功能是synchronized,因此一次只能有一个线程。

我不确定我理解你的问题......但如果你想让两个线程一次到某个地方,请看看Semaphore

答案 2 :(得分:2)

这是一个单身人士班吗? 如果不是那么这是一个问题,因为许多并发实例可能会更改icounter的值,此外它们将永久阻止它,因为没有线程可以在其实例对象上调用notify。

无论如何你应该在函数内移动同步并锁定iCount而不是实例,也使它变得不稳定。

public void myFunct(){ 
synchronized(iCount) {
while(iCount >= 3)
{
   try {
       wait();
   } catch (InterruptedException e) {
       e.printStackTrace();
 }
}
iCount++; 
}
//Do Stuffs
 //After operation decrement count
synchronized(iCount) {
 iCount--;
}
 notifyAll();

答案 3 :(得分:1)

您需要java.util.concurrent.Semaphore,初始化为2个许可。

对于您当前的代码 - 线程可能会缓存变量的值。请尝试添加volatile关键字。

答案 4 :(得分:1)

为什么不只是使用Semaphore

答案 5 :(得分:1)

另一种方法可能是使用最多两个线程的ThreadPoolExecutor

答案 6 :(得分:1)

此代码存在许多问题。其中:

  1. 您无法真正控制运行myFunct的线程数,因为该方法在实例级别上同步,而计数器是静态的。因此,在N个不同实例上运行的N个不同线程可以同时运行相同的方法。

  2. 通过多个线程操作计数器不是线程安全的。考虑同步它或使用AtomicInteger。

  3. 关于线程数的限制,请考虑使用Semaphore类。

相关问题