问题描述
我想在java中调用一个方法,但是是同步的和先进先出的。 目前我这样调用方法:
synchronized (synchronizeObject) {
executeMethode(object1,object2);
}
我发现,synchronized 实际上并不关心添加的顺序。 有没有简单的方法来强制 FIFO?
我不认为 ArrayBlockingQueue 在这里适用,至少在我看来不是这样,但我可能是错的
解决方法
这是一个片段:
public class AppTest {
@Test
void test() throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(8);
FairLockedMethod<Integer> method = new FairLockedMethod<>() {
@Override
protected void lockedMethod(Integer i) {
System.out.println(i);
try {
Thread.currentThread().wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 16; i++) {
int n = i;
pool.submit(() ->method.run(n));
}
pool.shutdown();
pool.awaitTermination(10,TimeUnit.SECONDS);
}
public static abstract class FairLockedMethod<T> {
protected abstract void lockedMethod(T value);
private final ReentrantLock lock = new ReentrantLock(true);
private final Condition condition = lock.newCondition();
private final Queue<Thread> queue = new LinkedBlockingDeque<>();
public void run(T value) {
queue.offer(Thread.currentThread());
lock.lock();
try {
while (queue.peek() != Thread.currentThread()) {
condition.await();
}
queue.poll();
condition.signalAll();
lockedMethod(value);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
这不是最有效的实现,但我能想到的最简单。