如何在不同的线程中运行监听器或在不同的线程中进行计算

Cas*_*dra 3 java multithreading guava

我正在尝试使用Google Guava构建缓存,并希望对过期的对象进行一些计算.如果删除了某个对象,removeListener会通知我.

如何在与主应用程序不同的线程中运行removeListener,或者将过期的对象(在下面的简单示例中,将是Integer 3)传递给处理计算的其他线程?

编辑:由于计算相当短,但经常发生,我宁愿不每次创建一个新线程(将是数千个线程),但有一个(或两个)计算所有对象.

简单的例子:

Cache<String, Integer> cache = CacheBuilder.newBuilder().maximumSize(100)
        .expireAfterAccess(100, TimeUnit.NANOSECONDS)
        .removalListener(new RemovalListener<String, Integer>() {
            public void onRemoval(final RemovalNotification notification) {
                if (notification.getCause() == RemovalCause.EXPIRED) {
                    System.out.println("removed " + notification.getValue());
                    // do calculation=> this should be in another thread
                }
            }
        })
        .build();
 cache.put("test1", 3);
 cache.cleanUp();
Run Code Online (Sandbox Code Playgroud)

Chr*_*irk 9

要在执行程序中运行侦听器,请使用RemovalListeners.asynchronous对其进行包装.

.removalListener(异步(new RemovalListener(){...},执行者))


JB *_*zet 6

使用Executors工厂方法之一创建ExecutorService ,并在每次需要时向此执行程序提交一个新的Runnable:

private ExecutorService executor = Executors.newSingleThreadExecutor();

...

public void onRemoval(final RemovalNotification notification) {
    if (notification.getCause() == RemovalCause.EXPIRED) {
        System.out.println("removed " + notification.getValue());
        submitCalculation(notification.getValue());
    }
}

private void submitCalculation(final Integer value) {
    Runnable task = new Runnable() {
        @Override
        public void run() {
            // call your calculation here
        }
    };
    executor.submit(task);
}
Run Code Online (Sandbox Code Playgroud)

  • 这正是上面所做的。它使用单个后台线程(因此称为“newSingleThreadExecutor()”)来执行所有提交的任务。不要混淆线程和 Runnables。Runnable 只是一段可执行代码。一个线程可以执行多段这样的代码。 (2认同)