简体   繁体   中英

Fast way to pass a simple java object from one thread to another

I have a callback which receives an object. I make a copy of this object, and I must pass it on to another thread for further processing. It's very important for the callback to return as fast as possible. Ideally, the callback will write the copy to some sort of lock-free container.

I only have the callback called from a single thread and one processing thread.

I only need to pass a bunch of doubles to the other thread, and I know the maximum number of doubles (around 40).

Any ideas? I'm not very familiar with Java, so I don't know the usual ways to pass stuff between threads.

If this is just a one-off thing - you get the 40- or so doubles, and want to start a new thread processing that, then you can do it like this:

public void callback(final double[] myDoubles)
{
  new Thread(){
   public void run() {
      // you can use myDoubles here. it will run on a separate thread.
   }}.start()   
};

If this is something that happens often, then you will need to look into thread pools and use a java.utils.concurrent.BlockingQueue . Despite the name, the queue will only block if it becomes full.

You can create an array of doubles the appropriate size which your callback method puts into the queue. The put() operation is very quick and so your callback method will not be delayed for long. (unless the queue is full.)

Your other thread will use the take() method on the queue to get the object when an object is available. The take() method blocks until an object is available - if you don't want that, but prefer to keep the thread running, doing other things, then use poll() instead.

One final thing to consider is - do you want just one worker thread handling the doubles from the callback, or do you want several? Having one thread makes sense when the work needs to be done one at a time - eg if you write the array to a file, there's usually no point having multiple threads doing this. Buf if the work done on each array is independent, then it's a good candidate for having multiple worker threads.

On how to "pass stuff between threads", keep in mind that the most important part of a thread in Java is the target , an instance of a class that implements java.lang.Runnable . If you construct a Thread object without passing in a Runnable instance, then the target is the Thread object itself (because java.lang.Thread implements java.lang.Runnable ). Otherwise, you are likely creating a custom class that implements Runnable , constructing an instance of this class, and passing it to a newly-constructed Thread instance. In this case, the instance of the custom class is the target.

Ensuring that the thread, basically the Runnable object, has access to an object is equivalent to ensuring that the Runnable object has a reference to the object as an instance variable, making the object accessible to the run method that is being executed in the thread.

Here is an example of how to pass a copy of a double array to a newly-created thread:

class MyRunner implements Runnable
{
    double[] m_data;

    public MyRunner(double[] data)
    {
        this.m_data = data;
    }

    public void run()
    {
        // this code is executed in a thread. It can access `m_data`.
    }
}

public class Callback
{
    public void doCallback(double[] data)
    {
        double[] dataCopy = null;
        if (data != null) {
            dataCopy = new double[data.length];
            System.arraycopy(data, 0, dataCopy, 0, data.length);
        }
        MyRunner target = new MyRunner(dataCopy);
        Thread worker = new Thread(target);
        worker.start();
    }
}

Create an implementation of Runnable that is constructed with the array of doubles and then pass it into a thread pool executor .

Like so:

public class MyDoublesProcessor implements Runnable {
    double[] doublesArray;
    public MyDoublesProcessor(double[] array) {
        doublesArray = array;
    }

    public void run() {
        //do stuff with array
    }
}

Executor exec = Executors.newFixedThreadPool(1);

void callback(double[] array) { //or whatever your callback is
    exec.execute(new MyDoublesProcessor(array));
}

Will you be creating a new Thread, or do you need to access another thread that already exists?

In case 1, you could just request a new Thread from a threadpool, pass it the information, tell it to run, then return.

In case 2, you might need to create an intermediate thread that you can pass your data to, then it holds onto the data and attempts to call a synchronized function on (for instance) a data processing thread. If you don't pass to an intermediate thread, you have no idea how long you might block on passing data to your other synchronized thread.

From the java essentials on threadpooling:

http://java.sun.com/docs/books/tutorial/essential/concurrency/pools.html

The newCachedThreadPool method creates an executor with an expandable thread pool. This executor is suitable for applications that launch many short-lived tasks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM