java - Java 中方法引用作为方法参数是线程安全的吗

标签 java multithreading thread-safety method-reference

我有以下情况:

interface ValueBinding<T> {
    public void setValue(T input);
}

public enum FacesBinding {
    VALUE;
    public void bindString(ValueBinding<String> fcn, HttpServletRequest req, String param){
        try {
            String val = req.getParameter(param);
            if( val != null )
                fcn.setValue(val);
        } catch (Exception e) { }        
    }
    public void bindBoolean(ValueBinding<Boolean> fcn, HttpServletRequest req, String param){
        try {
            fcn.setValue(req.getParameter(param) != null);
        } catch (Exception e) { }        
    }
    public void bindInt(ValueBinding<Integer> fcn, HttpServletRequest req, String param){
        try {
            int val = Integer.parseInt(req.getParameter(param));
            fcn.setValue(val);
        } catch (Exception e) { }        
    }
    public void bindLong(ValueBinding<Long> fcn, HttpServletRequest req, String param){
        try {
            long val = Long.parseLong(req.getParameter(param));
            fcn.setValue(val);
        } catch (Exception e) { }        
    }
...
...
}

我在这样的“多线程”环境中使用它:

并发线程正在调用此方法

            @Override // concurrent Threads are calling this method
            public Category initData(FacesContext facesContext) throws Exception {
                Category entity = new Category();
                HttpServletRequest req = facesContext.getRequest();
                FacesBinding.VALUE.bindLong(entity::setId, req, Table.Category.Field.ID.name());
                FacesBinding.VALUE.bindString(entity::setName, req, Table.Category.Field.NAME.name());

                FacesBinding.VALUE.bindInt(entity::setPosition, req, Table.Category.Field.POSITION.name());
                FacesBinding.VALUE.bindBoolean(entity::setLocalized, req, Table.Category.Field.LOCALIZED.name());           
                return entity;
            }

FacesBinding.VALUE.bindLong(entity::setId, req, Table.Category.Field.ID.name());

100% 线程安全当我传递方法引用(接口(interface))entity::setId作为枚举对象(单例)中方法的参数?

注意:

entity::setId

entity::setName

entity::setPosition

...等等。所有这些方法都是标准的 java setter 方法

public void setId(long id) {
        this.id = id;
    }
public void setName(String name) {
        this.name = name;
    }
....

更新:

具体来说:

Category entity = new Category();
entity.setId(5);//thread safe for sure

100%等于

FacesBinding.VALUE.bindLong(entity::setId, ...);

事实上FacesBinding ist Singleton 和方法引用bindLong(entity::setId, ...)使其线程不安全?

最佳答案

如果您的 setId 方法是线程安全的,那么您的方法引用调用将是线程安全的,仅此而已。

方法引用是创建 ValueBinding 对象的奇特简写。当它们被编译时,将会有一个私有(private)内部类来实现您的函数接口(interface)并调用您指定的方法。由于您指定了属于某个对象的方法,因此该内部类也将相当于具有接受您的Category对象的构造函数,以及一个用于存储它的私有(private)字段(我说过相当于因为默认情况下实现不限于此行为(如果它们可以证明并选择任何其他行为)。

关于java - Java 中方法引用作为方法参数是线程安全的吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41896724/

相关文章:

java - 在 Java 中查找并返回 TreeSet 中的元素

c# - 未经授权的访问异常 : how to wait on input from user. Windows Phone c#

c++ - 被连续迭代的线程安全无序映射

c++ - 头文件中定义的线程函数给​​出类型转换错误

objective-c - NSLock + 原子属性 vs 非原子

c# - ThreadPool.QueueUserWorkItem 是线程安全的吗?

java - 使用适配器应对两种不同情况

java - 如何获取带有日期、小时和分钟的 ISO 8601 格式的当前时刻?

java - 未知错误 : DevToolsActivePort file doesn't exist

java - 线程安全地从一个列表中删除/添加元素到另一个列表