Home > Enterprise >  How to get the object on a specific thread?
How to get the object on a specific thread?

Time:03-10

I have a runnable created by ThreadPoolExecutor.execute

for example:

class myObj implements Runnable{{
   int m_id;
   myObj(int id) {n_id = id}
   @Override
    public void run() { }
}

m_threadPoolTaskExecutor.execute(
    new myObj(9);
);

Then after the run, how can I get the myObj instance from that thread? So can I iterate through the thread pool and find mObj that matches the m_id == 9?

CodePudding user response:

Threads are Runnable, but not all Runnables are Threads. When you submit a Runnable to a thread pool the expectation is that the pool supplies the actual thread, your Runnable is only a task intended to be executed by some thread. When the thread pool worker that is assigned your task finishes processing it, it grabs another task and it doesn't have your Runnable anymore.

You could keep a reference to your Runnable, but then you'd have to deal with updates made across threads and we'd have to deal with using volatile, AtomicInteger, or whatever. Your code doesn't just automatically see changes made by another thread, the JVM needs specific signs that it looks out for. The whole model of submitting a runnable to a pool, then looking at the runnable later is very ugly and error-prone.

If you change your Runnable into a Callable and have it use a Future to return the int you need back, then the memory visibility issues will be handled for you.

Pass the Callable into the ExecutorService submit method that returns a Future. You can call isDone on the Future to see if the task is completed yet, then call get on it to retrieve the value returned from the Callable.

I'm not clear on what exactly you want to find in the task after it has been executed. My advice is make a separate immutable object with the values you want. Here I'm calling it MyResult. so the Callable would look like this:

class MyObj implements Callable<MyResult> {{
    
    int m_id;
    MyObj(int id) {n_id = id}
    
    @Override
    public MyResult call() { 
        return new MyResult(1,2);
    }
}

class MyResult {
    final val1;
    final val2;
    public MyResult(int val1, int val2) {
        this.val1 = val1;
        this.val2 = val2;
    }
}
  • Related