Are method References as method parameters thread safe in Java

*爱你&永不变心* 提交于 2020-05-16 08:58:07

问题


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)?

NOTE:

entity::setId

entity::setName

entity::setPosition

...etc. ALL these methods are standard java setter methods

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

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

does the fact that FacesBinding ist Singleton and the method Reference in bindLong(entity::setId, ...) makes it thread-unsafe??


回答1:


Your method reference call will be thread-safe if your setId method is thread-safe, nothing more and nothing less.

Method reference is a fancy shorthand for creating your ValueBinding objects. 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).



来源:https://stackoverflow.com/questions/41896724/are-method-references-as-method-parameters-thread-safe-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!