简体   繁体   English

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

[英]Are method References as method parameters thread safe in Java

i have the following scenario:我有以下情况:

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) { }        
    }
...
...
}

and i use it in a "multithreaded" Environment like this:我在这样的“多线程”环境中使用它:

concurrent Threads are calling this method并发线程正在调用此方法

            @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;
            }

is

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

100% Thread safe when i pass a method reference (interface) entity::setId as parameter of a method in enum Object (Singleton)?当我将方法引用(接口) entity::setId作为枚举对象(单例)中方法的参数传递时, 100% 线程安全

NOTE:笔记:

entity::setId

entity::setName

entity::setPosition

...etc. ...等等。 ALL these methods are standard java setter methods所有这些方法都是标准的 java setter 方法

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

UPDATE:更新:

to be concrete: ARE是具体的:

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

100% equal to 100% 等于

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

does the fact that FacesBinding ist Singleton and the method Reference in bindLong(entity::setId, ...) makes it thread-unsafe?? FacesBinding Singleton 并且bindLong(entity::setId, ...)的方法 Reference bindLong(entity::setId, ...)使它成为线程不安全的?

Your method reference call will be thread-safe if your setId method is thread-safe, nothing more and nothing less.如果您的setId方法是线程安全的,那么您的方法引用调用将是线程安全的,仅此而已。

Method reference is a fancy shorthand for creating your ValueBinding objects.方法引用是创建ValueBinding对象的一种奇特的速记。 When they are compiled, there will be a private inner class of sorts that implements your functional interface and calls the method you specified.当它们被编译时,会有一个私有的内部类来实现你的功能接口并调用你指定的方法。 Since you specified method that belongs to an object, this inner class will also be equivalent to having constructor that accepts your Category object, and a private field to store it (I said equivalent to because by default implementations are not limited to this behavior if they can justify and choose any other).由于您指定了属于一个对象的方法,这个内部类也相当于拥有接受您的Category对象的构造函数和一个私有字段来存储它(我说相当于因为默认情况下实现不限于此行为,如果它们可以证明并选择任何其他)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM