`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;
            }
        }
    }
}
```
final Supplier<T> delegate;
    ThreadSafeSupplier(Supplier<T> delegate) {
      this.delegate = checkNotNull(delegate);
    }
    @Override
    public T get() {
      synchronized (delegate) {
        return delegate.get();
      }
    }
    @Override
    public String toString() {
      return "Suppliers.synchronizedSupplier(" + delegate + ")";
    }
    private static final long serialVersionUID = 0;
  }
  /**
   * Returns a function that accepts a supplier and returns the result of invoking {@link
   * Supplier#get} on that supplier.
   *
   * <p><b>Java 8 users:</b> use the method reference {@code Supplier::get} instead.
   *
   * @since 8.0
   */
  public static <T> Function<Supplier<T>, T> supplierFunction() {
    @SuppressWarnings("unchecked") 
    SupplierFunction<T> sf = (SupplierFunction<T>) SupplierFunctionImpl.INSTANCE;
    return sf;
  }
  private interface SupplierFunction<T> extends Function<Supplier<T>, T> {}