Functions { public static <T,R> Function<T,R> synchronizedFunction(final Function<T,R> function) { if (isImmutable(function) && !(function instanceof AutoCloseable)) return function; return new ThreadSafeFunction<T,R>(function); }  @SuppressWarnings("unchecked") static UnaryOperator<T> identity(); @SuppressWarnings("unchecked") static Function<T,Integer> zero(); static Function<T,Integer> unpartitioned(); static void closeFunction(Object function); static Function<T,R> synchronizedFunction(final Function<T,R> function); static Supplier<T> synchronizedSupplier(final Supplier<T> function); static Consumer<T> synchronizedConsumer(final Consumer<T> function); static BiFunction<T,U,R> synchronizedBiFunction(final BiFunction<T,U,R> function); static boolean isImmutable(Object function); static boolean isImmutableClass(Class<?> clazz); static Runnable delayedConsume(Consumer<T> consumer, T value); static Runnable runWithFinal(Runnable action, Runnable finalAction); @SuppressWarnings("unchecked") static Consumer<T> discard(); @SuppressWarnings("unchecked") static Predicate<T> alwaysTrue(); @SuppressWarnings("unchecked") static Predicate<T> alwaysFalse();  }
@Test public void testSynchronizedFunction() { Function<Integer,String> f1 = v -> Integer.toString(v); assertSame(f1, Functions.synchronizedFunction(f1)); Function<Integer,Integer> f2 = v -> v * 2; assertSame(f2, Functions.synchronizedFunction(f2)); int a = 7; Function<Integer,Integer> f3 = v -> v + a; assertSame(f3, Functions.synchronizedFunction(f3)); int[] aa = new int[1]; Function<Integer,Integer> f4 = v -> v + aa[0]; assertNotSame(f4, Functions.synchronizedFunction(f4)); aa[0] = 7; int r4 = f4.apply(2); assertEquals(9, r4); aa[0] = 13; r4 = f4.apply(9); assertEquals(22, r4); Function<Integer,Integer> f5 = new F5(); add = 99; try { f5.apply(8); fail("Expected IllegalMonitorStateException"); } catch (IllegalMonitorStateException e) { } Function<Integer,Integer> f5s = Functions.synchronizedFunction(f5); assertNotSame(f5, f5s); int r5s = f5s.apply(18); assertEquals(117, r5s); Function<Integer,Integer> f6 = new F6(); assertNotSame(f6, Functions.synchronizedFunction(f6)); }