If you just wish to chain the calls together then they will always run in the same thread unless one piece of code spawns its own threads: i.e. if you say
A:foo.doSomething();
B:bar.doSomethingElse();
both calls will always be run in the same thread (or at least start their, however they may spawn their own threads).
It is, however not possible to have code specify which Thread it wishes to run in i.e. IN seperate execution paths that are not occuring in the same thread:
A:foo.doSomething(commonThread);
and in a different thread where "commonThread" is a shared Thread object.
B:bar.doSomethingElse(commonThread);
What you have to do is have the Thread where you want the code to run execute be able to accept tasks that you want to have run in that thread. This is how things like SwingUtilities.invokeXXX(Runnable r) work to get things on the EDT. Here is a rough example of what this might look like (note this is a quick example and not entirely correct/robust)
class WorkerThread implements Runnable{
BlockingDeque<Runnable> tasks = ...;
Thread t;
public void startWorker(){
if(t != null && t.isAlive())return;
t = new Thread(this);
t.start();
}
public void run(){
while(true){
Runnable nextTask = tasks.getFirst();
nextTask.run();
}
}
public void doTaskInThread(Runnable r){
if(Thread.currentThread() == this.t){
//already in the worker thread, do immediately
r.run();
}else{
//not in the worker thread so queue
//alternatively eliminate the first test condition and always queue
tasks.push(r);
}
}
}
While it may be possible to engineer something like the above into the code it would likely be very difficult especially if you do not have access to the source for all of the plugins you wish to control.