我有一个不寻常的问题。 我有一个函数,这个函数的操作一次可以由两个线程完成。
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();
}
我想要做的是,我想只允许两个线程做一些操作,其他线程必须等待。
但是这里前两个线程递增计数并执行操作,其他线程进入等待状态但是没有得到通知。
我想我忽略了一些事情。
答案 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)
此代码存在许多问题。其中:
您无法真正控制运行myFunct的线程数,因为该方法在实例级别上同步,而计数器是静态的。因此,在N个不同实例上运行的N个不同线程可以同时运行相同的方法。
通过多个线程操作计数器不是线程安全的。考虑同步它或使用AtomicInteger。
关于线程数的限制,请考虑使用Semaphore类。