All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlassian.util.concurrent.Lazy Maven / Gradle / Ivy

Go to download

This project contains utility classes that are used by various products and projects inside Atlassian and may have some utility to the world at large.

The newest version!
package io.atlassian.util.concurrent;

import static io.atlassian.util.concurrent.Timeout.getNanosTimeout;
import static io.atlassian.util.concurrent.Timeout.timeoutFactory;
import static io.atlassian.util.concurrent.Timeout.TimeSuppliers.NANOS;
import static java.util.Objects.requireNonNull;

import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Factory for creating lazily populated references.
 *
 * @since 2.1
 */
public final class Lazy {
  /**
   * Memoizing reference that is lazily computed using the supplied factory.
   * 

* The {@link Supplier factory} is not held on to after it is used, enabling * it to be garbage collected. * * @param the type. * @param factory for populating the initial value, called only once. * @return a supplier */ public static Supplier supplier(final Supplier factory) { return new Strong<>(factory); } /** * Memoizing reference that expires the specified amount of time after * creation. * * @param the type. * @param factory for populating the initial value, called only once. * @param time the amount * @param unit the units the amount is in * @return a supplier */ public static Supplier timeToLive(final Supplier factory, final long time, final TimeUnit unit) { return new Expiring<>(factory, () -> new TimeToLive(getNanosTimeout(time, unit))); } /** * Memoizing reference that expires the specified amount of time after the * last time it was accessed. * * @param the type. * @param factory for populating the initial value, called only once. * @param time the amount * @param unit the units the amount is in * @return a supplier */ public static Supplier timeToIdle(final Supplier factory, final long time, final TimeUnit unit) { return new Expiring<>(factory, () -> new TimeToIdle(timeoutFactory(time, unit, NANOS))); } /** * Returns a {@link io.atlassian.util.concurrent.ResettableLazyReference} * which creates the value by applying the provided * {@link java.util.function.Supplier}. * * @param supplier that creates the value that will be held by the * {@link io.atlassian.util.concurrent.ResettableLazyReference}. * @param the type of the contained element. * @return a {@link io.atlassian.util.concurrent.ResettableLazyReference} * which creates the value by applying the provided * {@link java.util.function.Supplier}. * @since 3.0 */ public static ResettableLazyReference resettable(final Supplier supplier) { return new ResettableLazyReference() { @Override protected T create() throws Exception { return supplier.get(); } }; } // // inners // /** * Never expires. */ static final class Strong extends LazyReference { // not private for testing volatile Supplier supplier; Strong(final Supplier supplier) { this.supplier = requireNonNull(supplier); } @Override protected T create() throws Exception { try { return supplier.get(); } finally { supplier = null; // not needed any more } } } /** * Tracks timeout from construction time */ static final class TimeToLive implements Predicate { private final Timeout timeout; TimeToLive(final Timeout timeout) { this.timeout = timeout; } @Override public boolean test(final Void input) { return !timeout.isExpired(); } } /** * Tracks timeout since last time it was asked. Once timed-out it stays that * way. */ static final class TimeToIdle implements Predicate { private volatile Timeout lastAccess; private final Supplier timeout; TimeToIdle(final Supplier timeout) { this.timeout = requireNonNull(timeout); lastAccess = timeout.get(); } @Override public boolean test(final Void input) { final boolean alive = !lastAccess.isExpired(); if (alive) { lastAccess = timeout.get(); } return alive; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy