The JavaDelegate implementation is indeed shared between process-instances. Process-variables (set when starting the process, through API or by activities in the process) are stored in the database for each process-instance.
So if you have a process that is started by user X, you can use the activiti:initiator="personWhoStarted" construction (see user guide). Once your service-task is reached, you can use the DelegateExecution to extract the value of the "personWhoStarted" variable for the current process instance, using delegateExecution.getVariable("personWhoStarted"). This value can now be used to call your external service, being 100% sure that the call to that service is using the user for the process involved.
Another way to extract variables from the execution in a service-task is to use Field-injection (see user guide again). This field is stateless and thus can be shared between all instances. Once the javaDelegate is called, you can get the value of the field, based on the current process-instance (by passing in the DelegateExecution when getting value).
If you don't want to use JavaDelegates that are shared, you can always use, for example, spring-beans (using activiti:delegateExpression) or methods on spring-beans (or non-spreing beans set at configuration time), passing in execution-variables along with it (activiti:expression). Again, this is described in the user guide in more detail.
If you really really really want to create your own delegate classes, you can have the "delegateExpression" return a new instance every time. off course, if you think about the "stateless" nature of the process-logic Java, it makes no sense to have new instance every time. The logic in the delegates should use the process-variables and state…