2017-01-27 4 views
1

ich habe das folgende Szenario:Sind Verfahren Referenzen als Methodenparameter Thread-sicher in 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) { }   
    } 
... 
... 
} 

und ich verwende es in einem „multithreaded“ Umwelt wie folgt aus:

gleichzeitige Threads sind diese Methode aufrufen

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

ist

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

100% threadsicher wenn i eine Methode Referenz (Schnittstelle) entity::setId als Parameter einer Methode in enum Object (Singleton) pass?

HINWEIS:

entity::setId 

entity::setName 

entity::setPosition 

... etc. Alle diese Methoden sind Standard-Java-Setter-Methoden

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

UPDATE:

sein Beton: SIND

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

100% gleich

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

macht die Tatsache, dass FacesBinding Singleton ist und die Methode Reference in bindLong(entity::setId, ...) macht es Thread-unsicher?

+0

Ich sehe nicht, was diesen Thread sicher machen könnte. Aber das verdienen einige Forschung – AxelH

+0

@AxelH, ist nicht die Tatsache, dass die Methode bindLong (entity :: setId, ...) eine Methode einer neuen Instanz des Objekts (neue Category() in meinem Fall) macht es thread sicher? –

Antwort

1

Ihr Methodenreferenz-Aufruf ist Thread-sicher, wenn Ihre setId Methode threadsicher ist, nicht mehr und nicht weniger.

Methodenreferenz ist eine schicke Kurzschrift zum Erstellen Ihrer ValueBinding Objekte. Wenn sie kompiliert werden, gibt es eine private innere Klasse von Arten, die Ihre funktionale Schnittstelle implementiert und die von Ihnen angegebene Methode aufruft. Da Sie eine Methode angegeben haben, die zu einem Objekt gehört, ist diese innere Klasse auch entspricht Konstruktor, der Ihr Category Objekt akzeptiert, und ein privates Feld, um es zu speichern (ich sagte Äquivalent, weil Implementierungen standardmäßig nicht auf dieses Verhalten beschränkt sind) wenn sie andere rechtfertigen und wählen können).

+0

setId-Methode ist eine übliche Java-Setter-Methode, da es zu einer bestimmten Instanz des Category Object gehört, ist threadsicher. bedeutet dies, dass meine Implementierung über 100% threadsicher ist, obwohl ich sie als Methodenname im Singleton-Objekt (enum) verwende? –

+1

Ich würde sagen, dass es als einfacher Setter eher ** nicht ** threadsicher machen wird, weil mit Thread-Sicherheit normalerweise geordnete Schreibvorgänge gemeint sind, und da keine Synchronisation vorhanden ist, weder auf "ValueBinding" noch auf "setId "und mit der zusätzlichen Tatsache, dass jedes Ihrer ValueBinding-Objekte von mehreren gleichzeitigen Threads nach Ermessen seiner Benutzungsseite gemeinsam genutzt werden kann. –

+0

In meinem Fall rufen die gleichzeitigen Threads die Methode initData (..) auf. Wie Sie in dieser Methode sehen, erstelle ich eine neue Instanz meines Category Objects. Kein Thread hat direkten Zugriff auf die Setter-Methoden. Jeder Aufruf von initData (..) wird zu einer neuen Instanz. Deshalb habe ich seinen Thread als sicher bezeichnet. Aber ich bin mir nicht sicher, ob dies der Fall ist, indem ich Methodenreferenzen in einem enum-Objekt verwende. Hier sind meine Sorgen. –

Verwandte Themen