在Java中方法引用作为方法参数线程安全吗? [英] Are method References as method parameters thread safe in Java

查看:634
本文介绍了在Java中方法引用作为方法参数线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:

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());

当我通过方法引用(接口)entity::setId作为枚举对象(单例)中方法的参数时,

100%线程安全 )?

注意:

entity::setId

entity::setName

entity::setPosition

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

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

更新:

具体来说: ARE

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

100%等于

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

具有FacesBinding ist Singleton和bindLong(entity::setId, ...)中的Reference方法是否使其成为线程不安全的事实吗?

解决方案

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

方法参考是创建ValueBinding对象的简便方法.当它们被编译时,将有一个私有的内部类来实现您的功能接口并调用您指定的方法.由于您指定了属于对象的方法,因此该内部类也将等效于,具有接受您的Category对象的构造函数和一个私有字段来存储它(我说等效于因为默认情况下,如果可以证明并选择其他任何实现,则实现不限于此行为.

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

解决方案

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

这篇关于在Java中方法引用作为方法参数线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆