In short yes it is multi-threaded the usual pattern would be one endpoint being passed multiple messages potentially by concurrent threads.
Currently if you are using a PollableChannel (queue, rendezvous) then the concurrency can be controlled by the poller. If you have provided an instance of task executor for the endpoint then this will be used to carry out the poll so for example every five seconds a new polling runnable will be passed to the task executor. By default the polling runnable will keeping taking messages from the queue and calling the onMessage method of the consumer until there are no messages left. This can be controlled with the max messages per poll attribute on the poller element. In the case that this poll takes more than fives seconds you would then have multiple threads taking messages from the same queue and invoking the same consumer.
If you are using the default channel, a DirectChannel then the thread calling send on the channel is used to call the consumer. So concurrency would be provided by the number of sender threads.
If what you want is a large number of threads invoking the consumer then something like the below may be suitable. By using a publish-subscribe channel which has a task executor each message put on the queue results in at least one runnable being executed by a thread from the pool invoking the consumer. It may be more than one runnable per message since the channel, as its name suggests supports one to many message sending.
Code:
<si:message-bus />
<si:publish-subscribe-channel id="requests" task-executor="workers"/>
<bean id="consumer" class="Consumer"/>
<si:service-activator ref="consumer" input-channel="requests" />
<si:thread-pool-task-executor id="workers" max-size="20" core-size="10"/>