cancel
Showing results for 
Search instead for 
Did you mean: 

Variables in expressions and thread safety

jcoveron
Champ in-the-making
Champ in-the-making
Hi,

I am using Java Service Task to get and set some processing variables. Here is an example:


public class Analysis {

   public void MediaInfoAction(DelegateExecution execution, String Nickname)
   {
      EssenceMediaInfo MediaInfo = new EssenceMediaInfo();

      HashMap<String, String> NicknameDetails = MediaInfo.ParseNicknameProperties(execution, Nickname);

      String JsonString = "{"
            + "\"GeneralVideoCount\" : \"%VideoCount%\", "
            + "\"GeneralAudioCount\" : \"%AudioCount%\", "
            + "\"GeneralCompleteName\" : \"%CompleteName%\", "
            + "\"GeneralFormat\" : \"%Format%\", "
            + "\"GeneralFormatCommercial\" : \"%Format_Commercial%\", "
            + "\"GeneralFormatProfile\" : \"%Format_Profile%\", "
            + "\"GeneralFormatSettings\" : \"%Format_Settings%\", "
            + "\"GeneralFileExtension\" : \"%FileExtension%\", "
            + "\"GeneralFileSize\" : \"%FileSize%\", "
            + "\"GeneralOverallBitRateMode\" : \"%OverallBitRate_Mode%\", "
            + "\"GeneralOverallBitRateBps\" : \"%OverallBitRate%\", "
            + "\"GeneralOverallBitRateMbps\" : \"%OverallBitRate/String%\", "
            + "\"DidMediaInfoGeneralAnalysis\" : \"true\"}";
      
      JsonString = MediaInfo.GetFilePropertyByJson("General", JsonString);

      SetVariables(execution, JsonString);
   }

   public void SetVariables(DelegateExecution execution, String JsonString) throws ParseException
   {
      ContainerFactory containerFactory = new ContainerFactory()
      {
         public List creatArrayContainer() {
           return new LinkedList();
         }

          public Map createObjectContainer() {
            return new LinkedHashMap();
          }               
      };
      
      Map json = (Map) this.JsonParser.parse(JsonString, containerFactory);
      Iterator iter = json.entrySet().iterator();
      
       while(iter.hasNext())
       {
         Map.Entry entry = (Map.Entry)iter.next();
         execution.setVariable(entry.getKey().toString(), entry.getValue().toString());
       }
   }

}


The same function can be called from multiple java service tasks executed after a parallel gateway within the same process instance. Also, the same process instance can be started multiple times and almost simultaneously.

As recommended in the user guide, we try to use only local variables inside the function, and we avoid using any member variables. This is because we want to achieve the java service task to execute concurrently.

Our parallel gateway have the activiti:async="true" activiti:exclusive="false" property as well as the java service tasks.

If we make the function thread safe (using synchronize), we cannot execute the task concurrently. But if we remove the thread safe (not using synchronize), the task is executed concurrently but variables values from a process instance are update by the values from another instance.

Our question is, how can we achieve the task concurrency and thread safety? Hope you can give us some tips on this.

The version we are using is 5.17.0.

We appreciate all your help in advance and congratulations on the software. It is very powerful.

Best regards
1 REPLY 1

trademak
Star Contributor
Star Contributor
The only way to make sure that a variable is updated by only one service task at a time, you have to set activiti:exclusive to true. Then the Engine will execute one task at a time.

Best regards,