Functions { public static <T> Consumer<T> synchronizedConsumer(final Consumer<T> function) { if (isImmutable(function) && !(function instanceof AutoCloseable)) return function; return new ThreadSafeConsumer<T>(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 testSynchronizedConsumer() { Consumer<Integer> f1 = v -> {}; assertSame(f1, Functions.synchronizedConsumer(f1)); int a = 7; Consumer<Integer> f2 = v -> consumer(a + v); assertSame(f2, Functions.synchronizedConsumer(f2)); int[] aa = new int[1]; Consumer<Integer> f3 = v -> aa[0] = v; assertNotSame(f3, Functions.synchronizedConsumer(f3)); aa[0] = 7; f3.accept(85); assertEquals(85, aa[0]); Consumer<Integer> f4 = new C4(); add = 127; try { f4.accept(99); fail("Expected IllegalMonitorStateException"); } catch (IllegalMonitorStateException e) { } Consumer<Integer> f4s = Functions.synchronizedConsumer(f4); assertNotSame(f4, f4s); f4s.accept(2421); assertEquals(2421, add); Consumer<Integer> f5 = new C5(); assertNotSame(f5, Functions.synchronizedConsumer(f5)); }