`Streams.concat` functions as expected when its arguments are finite streams.
If we concat two streams: the first is finite and the second is infinite, then obviously we get an infinite stream. But we can iterate over a limited number of elements. This is the scenario where the program hangs.

```java
import com.google.common.collect.Streams;

import java.util.PrimitiveIterator;
import java.util.stream.IntStream;

public class MyMain {
    public static void main(String[] args) {

        IntStream stream123 = IntStream.of(1, 2, 3);
        IntStream stream4567 = IntStream.of(4, 5, 6, 7);
        IntStream stream1234567 = Streams.concat(stream123, stream4567);
        printFirstElements(stream1234567, 5);
        // output:
        // 1
        // 2
        // 3
        // 4
        // 5



        IntStream streamInfinite99 = IntStream.generate(() -> 99);
        printFirstElements(streamInfinite99, 3);
        // output:
        // 99
        // 99
        // 99

        IntStream stream123AndThenInfinite77 = Streams.concat(IntStream.of(1, 2, 3), IntStream.generate(() -> 77));
        printFirstElements(stream123AndThenInfinite77, 5);
        // output:
        // 1
        // 2
        // 3
        // and then program hangs
    }

    static void printFirstElements(IntStream stream, int count) {
        int counter = 0;
        for (PrimitiveIterator.OfInt iterator = stream.iterator(); iterator.hasNext(); ) {
            Integer next = iterator.next();
            System.out.println(next);
            counter++;
            if (counter == count) {
                break;
            }
        }
    }
}
```
static class ExpiringMemoizingSupplier<T> implements Supplier<T>, Serializable {
    final Supplier<T> delegate;
    final long durationNanos;
    transient volatile @Nullable T value;
    
    transient volatile long expirationNanos;
    ExpiringMemoizingSupplier(Supplier<T> delegate, long duration, TimeUnit unit) {
      this.delegate = checkNotNull(delegate);
      this.durationNanos = unit.toNanos(duration);
      checkArgument(duration > 0, "duration (%s %s) must be > 0", duration, unit);
    }
    @Override
    public T get() {
      
      
      
      
      
      
      long nanos = expirationNanos;
      long now = Platform.systemNanoTime();
      if (nanos == 0 || now - nanos >= 0) {
        synchronized (this) {