首页 > 解决方案 > Java同步方法调用但FIFO

问题描述

我想在java中调用一个方法,但要同步和先进先出。目前我这样调用方法:

synchronized (synchronizeObject) {
     executeMethode(object1, object2);
}

我发现,同步实际上并不关心添加的顺序。有没有一种简单的方法来强制先进先出?

我不认为 ArrayBlockingQueue 在这里适用,至少在我看来不是这样,但我可能错了

标签: javasynchronizationsynchronizedfifomethod-call

解决方案


这是一个片段:


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();
            }
        }
    }
}

这不是最有效的实现,但我能做到的最简单。


推荐阅读