指定java对象的超时

时间:2014-05-21 13:36:49

标签: java timeout

我想创建一个在达到超时时死掉的对象。我怎样才能做到这一点?

例如在伪代码中:

MyObject O = new MyObject(3000) ; // object created will be null after 3 seconds
wait(4000) ;
if (O == null)
  print("success") ;

有可能吗?

编辑:

实际上我正在使用MyObjects的大型地图。每个人在创造1分钟后都应该死亡。现在我正在考虑向MyObject添加一个creationDate,以及一个在其大小变得太大时检查我的MyObject映射的方法......并将null放到超时对象引用中。这将是另一种方法,考虑到我不需要所有对象一旦它们应该是空的事实(即,它们应该在1分钟后为空,但只要我的地图不是&n它就不那么重要了#39; t huge)。

3 个答案:

答案 0 :(得分:1)

如果你想杀死'程序中某一点的对象,您只需将变量赋值给null,垃圾收集就会自动完成。

// Make MyObject
MyObject O = new MyObject(3000);
// Wait 4 seconds
wait(4000);
// 'delete' it, the object made with `new MyObject(4000)` cannot be used anymore.
O = null;

答案 1 :(得分:1)

您应该创建ExecutorService并提交新的Runnable任务。它将返回一个Future的实例,您可以在该实例上花费所需的时间。

    Runnable task = new Runnable {
        @Override
        public void run() {
           // do your job
           // or just:
           MyObject O = new MyObject(3000);
           // some job on O object
        }
    };
    Future<?> future = Executors.newSingleThreadExecutor().submit(task);
    try {
        return future.get(TIMEOUT, TimeUnit.SECONDS);
    } catch (Throwable e) {
        log.error(e.getMessage(), e);            
    }

答案 2 :(得分:1)

修改

最适合您需求的是缓存。考虑Guava's Cache。缓存可以具有有限的大小(根据需要移除LRU元素),在一定时间后使元素过期等等。

他们的文档中的一个例子:

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
       .maximumSize(1000)
       .expireAfterWrite(10, TimeUnit.MINUTES)
       .removalListener(MY_LISTENER)
       .build(
           new CacheLoader<Key, Graph>() {
             public Graph load(Key key) throws AnyException {
               return createExpensiveGraph(key);
             }
           });

您可以实现类似于Java的Reference实现的自己的类。

例如:

import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

public class TimeoutReference<T> {
    public final AtomicReference<T> reference;

    /**
     * Create new instance
     * @param referent The reference
     * @param timeout minimum length of time the reference is guaranteed to not
     * be {@code null}.
     * @param unit the units of {@code timeout}
     * @throws NullPointerException if any parameter is {@code null}.
     */
    public TimeoutReference(T reference, long timeout, TimeUnit unit) {
        this.reference = new AtomicReference<>(
                Objects.requireNonNull(reference));
        ScheduledExecutorService service
                = Executors.newSingleThreadScheduledExecutor();
        service.schedule(() -> {
                    this.referent.set(null);
                    service.shutdown();
                }, timeout, unit);
    }

    /**
     * Returns the reference or {@code null} if the time has expired.
     */
    public T get() { // perhaps throw a checked exception for clarity.
        return reference.get();
    }
}

这似乎运作得相当好,

public static void main(String[] args) throws InterruptedException {
    // object created will be null after 3 seconds
    TimeoutReference<String> o = new TimeoutReference<>(
            "My non-null value", 3, TimeUnit.SECONDS);

    System.out.println("Before: " + o.get());
    Thread.sleep(4000) ;
    System.out.println("After: " + o.get());
}

哪个输出:

Before: My non-null value
After: null

我要提醒一种编程风格,null作为正确的用例可能容易出错。