当前位置: 首页 > 知识库问答 >
问题:

函数代替静态实用方法

谭越
2023-03-14
    private static Function<String, String> fnPrependString = (s) -> {
        return "prefix_" + s;
    };

现在的问题是,我是否可以创建这些函数一次,并像助手方法一样重用它们。

一个威胁是线程安全。我用一个简单的测试来检查这个JUnit测试:

package com.me.expt.lt.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;
import java.util.function.Function;

import org.junit.jupiter.api.Test;

import com.vmlens.api.AllInterleavings;

public class TestFunctionThreadSafety {
    private static Function<String, String> fnPrepend = (s) -> {
        System.out.println(s);
        return new StringBuffer("prefix_").append(s).toString();
    };

    @Test
    public void testThreadSafety() throws InterruptedException {
        try (AllInterleavings allInterleavings = new AllInterleavings(
                TestFunctionThreadSafety.class.getCanonicalName());) {
            ConcurrentMap<String, Integer> resultMap = new ConcurrentHashMap<String, Integer>();
            while (allInterleavings.hasNext()) {
                int runSize = 5;
                Thread[] threads = new Thread[runSize];
                ThreadToRun[] ttrArray = new ThreadToRun[runSize];
                StringBuffer sb = new StringBuffer("0");
                for (int i = 0; i < runSize; i++) {
                    if (i > 0)
                        sb.append(i);
                    ttrArray[i] = new ThreadToRun();
                    ttrArray[i].setS(sb.toString());
                    threads[i] = new Thread(ttrArray[i]);
                }
                for (int j = 0; j < runSize; j++) {
                    threads[j].start();
                }
                for (int j = 0; j < runSize; j++) {
                    threads[j].join();
                }
                System.out.println(resultMap);
                StringBuffer newBuffer = new StringBuffer("0");
                for (int j = 0; j < runSize; j++) {
                    if(j>0)
                        newBuffer.append(j);
                    assertEquals("prefix_" + newBuffer, ttrArray[j].getResult(), j + " fails");
                }
            }
        }
    }

    private static class ThreadToRun implements Runnable {
        private String s;
        private String result;

        public String getS() {
            return s;
        }

        public void setS(String s) {
            this.s = s;
        }

        public String getResult() {
            return result;
        }

        @Override
        public void run() {
            this.result = fnPrepend.apply(s);
        }

    }

}

我用的是VMLENS。我可以通过更改runsize变量来优化测试,这样可以检查随机性。目的是查看这些使用相同函数的多个线程是否因为并发访问而混淆了它们的输入。测试没有返回任何阴性结果。请对测试是否符合目标做出评论。

上面使用函数 的结果是否也可以应用于供应商 消费者

对函数和字节码的更多熟悉可能会帮助我回答这些问题。但是像这样的知识交流论坛可能会让我更快地得到答案,这些问题可能会引发读者更多的想法。

提前谢了。拉胡尔

共有1个答案

劳法
2023-03-14

作为一个用户,我真的不认为您需要花这么长的时间来证明JVM关于lambdas的保证。基本上,它们就像JVM的任何其他方法一样,没有特殊的内存或可见性影响:)

下面是一个较短的函数定义:

private static Function<String, String> fnPrepend = s -> "prefix_" + s;

this.result=fnprepend.application(s);

java prettyprint-override">  // Available as normal static method
  public static String fnPrepend(String s) {
    return "prefix_" + s;
  }
  
  // Takes a generic Function
  public static void someMethod(UnaryOperator<String> prefixer) {
    ...
  }

  // Coerce the static method to a function
  someMethod(Util::fnPrepend);


 类似资料:
  • 问题内容: 有效的Java说“考虑提供静态工厂方法而不是构造函数” 如果你有一个 为类A提供此方法是否有意义,而不是在代码中调用new A()。 问题答案: 请参阅此处以很好地说明您可能要执行此操作的主要原因。综上所述: 命名为“构造函数”。 如果合适,可以返回null。 如果合适,可以返回派生类的实例。 在实例化泛型类型的变量时减少冗长。 我想到了本文没有提及的另一个原因:可以实现有趣的逻辑来避

  • 本文向大家介绍Python使用函数默认值实现函数静态变量的方法,包括了Python使用函数默认值实现函数静态变量的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例展示了Python使用函数默认值实现函数静态变量的方法,具体方法如下: 一、Python函数默认值 Python函数默认值的使用可以在函数调用时写代码提供方便,很多时候我们只要使用默认值就可以了。 所以函数默认值在python中用到

  • 考虑以下代码,我们获取列表的块,加入它们并打印到标准输出: 代码工作正常。我想更改lambda调用(

  • 为GUI创建了登录类,将所有GUI构造添加到一个方法中,以便我可以在启动时从我的主类中调用它。调用方法抛出错误“'GUILoginPage.this'不能从静态上下文中引用”。 这方面有什么解决办法?我理解不能使用的原因。但我没有看到任何解决方案

  • 问题内容: 什么时候应该使用构造函数,什么时候应该使用静态方法? 您能用小片段解释一下吗?我略读了一些线程,但是我仍然不清楚。 问题答案: 当您只想返回该类型的新对象并且希望简单时,请使用公共构造函数。 一个很好的例子是StringBuilder,因为它是可变的,您可能每次都想要一个新对象。 当您可能想重用对象(尤其是不可变的对象),返回子类或描述结构时,请使用静态因子方法。一个很好的例子是Enu

  • 问题内容: 我对php中的静态功能有疑问。 假设我有一堂课 如果我这样做的话,没有问题。 也可以。 头等舱和二等舱有什么区别? 静态函数有什么特别之处? 问题答案: 在第一个类中,实际上是一个实例方法,您将其作为静态方法进行调用,但由于从未引用,所以您将其取消。 静态函数与该类相关联,而不是该类的实例。因此,在静态上下文中不可用(未指向任何对象)。