Advice on using Threads in a bundle

View: New views
4 Messages — Rating Filter:   Alert me  

Advice on using Threads in a bundle

by David Leangen-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hello!

I'm hoping that some people with more experience with OSGi and Java
Threads can advise me on the best way to use Threads in my bundle.

I have a service that takes a very long time to run. The service is of
course called from a separate bundle at any time.

>From what I've read, it seems that the thread should be created in the
Activator. I have no problem with that, but I'm not sure how I should
later call my service.

For example:

  public void start( final BundleContext bundleContext )
         throws Exception
  {
      final ClassLoader classLoader = getClass().getClassLoader();
      final Thread thread = new Thread()
      {
          public void run()
          {

Thread.currentThread().setContextClassLoader( classLoader );
              // Do something here (but WHAT??)
          }
      };

      thread.start();
  }


The process (from the consumer) should be something like this:

LoaderService loader =
(LoaderService)ServiceManager.getService( LoaderService.class )
loader.load();
// Loading is very long, but the call to load() should return
immediately


I don't see how to accomplish this with the thread being fired in
Activator.start(). Should a new thread not be created in
LoaderService.load() instead?

Otherwise, how do I go about this in practice?


Thanks for the advice!
Dave







--
You receive this message as a subscriber of the oscar@... mailing list.
To unsubscribe: mailto:oscar-unsubscribe@...
For general help: mailto:sympa@...?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

Re: Advice on using Threads in a bundle

by Richard S. Hall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

It sounds like this is a general Java thread programming question.
Basically, you create a thread that is waiting for requests and the
client thread that calls the load() method should insert a request for
the other thread. Here is an example:

class Loader {
    private List m_requests = new ArrayList();
    private LoaderRunnable m_runnable = null;

    public start() {
        new Thread(m_runnable = new LoaderRunnable()).start();
    }

    public stop() {
       m_runnable.stop();
    }

    // This method will be called by the client.
    public Result load() {
        synchronized (m_requests) {
            // Create a result placeholder and associate
            // it with a request.
            Result result = new Result(new Request());
            m_request.add(result.getRequest());
            // Wake up service thread.
            m_requests.notify();
            // Return result placeholder to client so it will
            // be able to check the result.
            return result;
        }
    }

    class LoaderRunnable implements Runnable {
        private List m_requests = new ArrayList();
        private boolean m_stop = false;
        public void run() {
            Request request = null;
            // Loop until stopped.
            while (!m_stop) {
                synchronized (m_requests) {
                    // Wait for a request.
                    while (!m_stop && (m_requests.size() == 0)) {
                        m_requests.wait();
                    }
                    // Get current request.
                    request = (Request) m_requests.remove(0);
                }
                // Perform the action associated with the request here...
            }
        }

        // Method to stop the service thread.
        public void stop() {
            m_stop = true;
        }
    }
}

That is the basic idea...there might be some bugs in here, because I
just typed this off the top of my head and I don't show all of the
details. Sounds like you may need to read up on Java threads and
concurrency.

-> richard
David Leangen wrote:

> Hello!
>
> I'm hoping that some people with more experience with OSGi and Java
> Threads can advise me on the best way to use Threads in my bundle.
>
> I have a service that takes a very long time to run. The service is of
> course called from a separate bundle at any time.
>
> >From what I've read, it seems that the thread should be created in the
> Activator. I have no problem with that, but I'm not sure how I should
> later call my service.
>
> For example:
>
>   public void start( final BundleContext bundleContext )
>          throws Exception
>   {
>       final ClassLoader classLoader = getClass().getClassLoader();
>       final Thread thread = new Thread()
>       {
>           public void run()
>           {
>
> Thread.currentThread().setContextClassLoader( classLoader );
>               // Do something here (but WHAT??)
>           }
>       };
>
>       thread.start();
>   }
>
>
> The process (from the consumer) should be something like this:
>
> LoaderService loader =
> (LoaderService)ServiceManager.getService( LoaderService.class )
> loader.load();
> // Loading is very long, but the call to load() should return
> immediately
>
>
> I don't see how to accomplish this with the thread being fired in
> Activator.start(). Should a new thread not be created in
> LoaderService.load() instead?
>
> Otherwise, how do I go about this in practice?
>
>
> Thanks for the advice!
> Dave
>
>
>
>
>
>  
> ------------------------------------------------------------------------
>
>
> --
> You receive this message as a subscriber of the oscar@... mailing list.
> To unsubscribe: mailto:oscar-unsubscribe@...
> For general help: mailto:sympa@...?subject=help
> ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
>  


--
You receive this message as a subscriber of the oscar@... mailing list.
To unsubscribe: mailto:oscar-unsubscribe@...
For general help: mailto:sympa@...?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

Re: Advice on using Threads in a bundle

by David Leangen-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Thanks a lot, Richard!

Yep, guess I need to dust off my book about threads...

But in terms of OSGi, what is the "best practice"? In this case, say
that LoaderImpl implements the Loader service and is loaded normally
when the bundle is activated (Activator.start()). Would I start the
thread after instantiating the implementation class and registering it?

Ex:

  public void start( final BundleContext bundleContext )
          throws Exception
  {
      m_serviceManager = new ServiceManager( bundleContext );
      bundleContext.addServiceListener( m_serviceManager );
      LoaderImpl loader = new LoaderImpl();
      m_serviceRegistration =
bundleContext.registerService( Loader.class, loader, null );
      loader.start();
  }



Or is there a better way?


Thanks again!
Dave




On Wed, 2006-07-19 at 03:49 -0400, Richard S. Hall wrote:

> It sounds like this is a general Java thread programming question.
> Basically, you create a thread that is waiting for requests and the
> client thread that calls the load() method should insert a request for
> the other thread. Here is an example:
>
> class Loader {
>     private List m_requests = new ArrayList();
>     private LoaderRunnable m_runnable = null;
>
>     public start() {
>         new Thread(m_runnable = new LoaderRunnable()).start();
>     }
>
>     public stop() {
>        m_runnable.stop();
>     }
>
>     // This method will be called by the client.
>     public Result load() {
>         synchronized (m_requests) {
>             // Create a result placeholder and associate
>             // it with a request.
>             Result result = new Result(new Request());
>             m_request.add(result.getRequest());
>             // Wake up service thread.
>             m_requests.notify();
>             // Return result placeholder to client so it will
>             // be able to check the result.
>             return result;
>         }
>     }
>
>     class LoaderRunnable implements Runnable {
>         private List m_requests = new ArrayList();
>         private boolean m_stop = false;
>         public void run() {
>             Request request = null;
>             // Loop until stopped.
>             while (!m_stop) {
>                 synchronized (m_requests) {
>                     // Wait for a request.
>                     while (!m_stop && (m_requests.size() == 0)) {
>                         m_requests.wait();
>                     }
>                     // Get current request.
>                     request = (Request) m_requests.remove(0);
>                 }
>                 // Perform the action associated with the request here...
>             }
>         }
>
>         // Method to stop the service thread.
>         public void stop() {
>             m_stop = true;
>         }
>     }
> }
>
> That is the basic idea...there might be some bugs in here, because I
> just typed this off the top of my head and I don't show all of the
> details. Sounds like you may need to read up on Java threads and
> concurrency.
>
> -> richard
> David Leangen wrote:
> > Hello!
> >
> > I'm hoping that some people with more experience with OSGi and Java
> > Threads can advise me on the best way to use Threads in my bundle.
> >
> > I have a service that takes a very long time to run. The service is of
> > course called from a separate bundle at any time.
> >
> > >From what I've read, it seems that the thread should be created in the
> > Activator. I have no problem with that, but I'm not sure how I should
> > later call my service.
> >
> > For example:
> >
> >   public void start( final BundleContext bundleContext )
> >          throws Exception
> >   {
> >       final ClassLoader classLoader = getClass().getClassLoader();
> >       final Thread thread = new Thread()
> >       {
> >           public void run()
> >           {
> >
> > Thread.currentThread().setContextClassLoader( classLoader );
> >               // Do something here (but WHAT??)
> >           }
> >       };
> >
> >       thread.start();
> >   }
> >
> >
> > The process (from the consumer) should be something like this:
> >
> > LoaderService loader =
> > (LoaderService)ServiceManager.getService( LoaderService.class )
> > loader.load();
> > // Loading is very long, but the call to load() should return
> > immediately
> >
> >
> > I don't see how to accomplish this with the thread being fired in
> > Activator.start(). Should a new thread not be created in
> > LoaderService.load() instead?
> >
> > Otherwise, how do I go about this in practice?
> >
> >
> > Thanks for the advice!
> > Dave
> >
> >
> >
> >
> >
> >  
> > ------------------------------------------------------------------------
> >
> >
> > --
> > You receive this message as a subscriber of the oscar@... mailing list.
> > To unsubscribe: mailto:oscar-unsubscribe@...
> > For general help: mailto:sympa@...?subject=help
> > ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
> >  



--
You receive this message as a subscriber of the oscar@... mailing list.
To unsubscribe: mailto:oscar-unsubscribe@...
For general help: mailto:sympa@...?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws

Re: Advice on using Threads in a bundle

by Richard S. Hall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hmm. In my example, you could always wait for the first call to the
service load() method to start the thread. This would be nice, since it
would be lazy, thus if your service is never used, it will never start a
thread.

-> richard

David Leangen wrote:

> Thanks a lot, Richard!
>
> Yep, guess I need to dust off my book about threads...
>
> But in terms of OSGi, what is the "best practice"? In this case, say
> that LoaderImpl implements the Loader service and is loaded normally
> when the bundle is activated (Activator.start()). Would I start the
> thread after instantiating the implementation class and registering it?
>
> Ex:
>
>   public void start( final BundleContext bundleContext )
>           throws Exception
>   {
>       m_serviceManager = new ServiceManager( bundleContext );
>       bundleContext.addServiceListener( m_serviceManager );
>       LoaderImpl loader = new LoaderImpl();
>       m_serviceRegistration =
> bundleContext.registerService( Loader.class, loader, null );
>       loader.start();
>   }
>
>
>
> Or is there a better way?
>
>
> Thanks again!
> Dave
>
>
>
>
> On Wed, 2006-07-19 at 03:49 -0400, Richard S. Hall wrote:
>  
>> It sounds like this is a general Java thread programming question.
>> Basically, you create a thread that is waiting for requests and the
>> client thread that calls the load() method should insert a request for
>> the other thread. Here is an example:
>>
>> class Loader {
>>     private List m_requests = new ArrayList();
>>     private LoaderRunnable m_runnable = null;
>>
>>     public start() {
>>         new Thread(m_runnable = new LoaderRunnable()).start();
>>     }
>>
>>     public stop() {
>>        m_runnable.stop();
>>     }
>>
>>     // This method will be called by the client.
>>     public Result load() {
>>         synchronized (m_requests) {
>>             // Create a result placeholder and associate
>>             // it with a request.
>>             Result result = new Result(new Request());
>>             m_request.add(result.getRequest());
>>             // Wake up service thread.
>>             m_requests.notify();
>>             // Return result placeholder to client so it will
>>             // be able to check the result.
>>             return result;
>>         }
>>     }
>>
>>     class LoaderRunnable implements Runnable {
>>         private List m_requests = new ArrayList();
>>         private boolean m_stop = false;
>>         public void run() {
>>             Request request = null;
>>             // Loop until stopped.
>>             while (!m_stop) {
>>                 synchronized (m_requests) {
>>                     // Wait for a request.
>>                     while (!m_stop && (m_requests.size() == 0)) {
>>                         m_requests.wait();
>>                     }
>>                     // Get current request.
>>                     request = (Request) m_requests.remove(0);
>>                 }
>>                 // Perform the action associated with the request here...
>>             }
>>         }
>>
>>         // Method to stop the service thread.
>>         public void stop() {
>>             m_stop = true;
>>         }
>>     }
>> }
>>
>> That is the basic idea...there might be some bugs in here, because I
>> just typed this off the top of my head and I don't show all of the
>> details. Sounds like you may need to read up on Java threads and
>> concurrency.
>>
>> -> richard
>> David Leangen wrote:
>>    
>>> Hello!
>>>
>>> I'm hoping that some people with more experience with OSGi and Java
>>> Threads can advise me on the best way to use Threads in my bundle.
>>>
>>> I have a service that takes a very long time to run. The service is of
>>> course called from a separate bundle at any time.
>>>
>>> >From what I've read, it seems that the thread should be created in the
>>> Activator. I have no problem with that, but I'm not sure how I should
>>> later call my service.
>>>
>>> For example:
>>>
>>>   public void start( final BundleContext bundleContext )
>>>          throws Exception
>>>   {
>>>       final ClassLoader classLoader = getClass().getClassLoader();
>>>       final Thread thread = new Thread()
>>>       {
>>>           public void run()
>>>           {
>>>
>>> Thread.currentThread().setContextClassLoader( classLoader );
>>>               // Do something here (but WHAT??)
>>>           }
>>>       };
>>>
>>>       thread.start();
>>>   }
>>>
>>>
>>> The process (from the consumer) should be something like this:
>>>
>>> LoaderService loader =
>>> (LoaderService)ServiceManager.getService( LoaderService.class )
>>> loader.load();
>>> // Loading is very long, but the call to load() should return
>>> immediately
>>>
>>>
>>> I don't see how to accomplish this with the thread being fired in
>>> Activator.start(). Should a new thread not be created in
>>> LoaderService.load() instead?
>>>
>>> Otherwise, how do I go about this in practice?
>>>
>>>
>>> Thanks for the advice!
>>> Dave
>>>
>>>
>>>
>>>
>>>
>>>  
>>> ------------------------------------------------------------------------
>>>
>>>
>>> --
>>> You receive this message as a subscriber of the oscar@... mailing list.
>>> To unsubscribe: mailto:oscar-unsubscribe@...
>>> For general help: mailto:sympa@...?subject=help
>>> ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
>>>  
>>>      
>
>
>  
> ------------------------------------------------------------------------
>
>
> --
> You receive this message as a subscriber of the oscar@... mailing list.
> To unsubscribe: mailto:oscar-unsubscribe@...
> For general help: mailto:sympa@...?subject=help
> ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
>  


--
You receive this message as a subscriber of the oscar@... mailing list.
To unsubscribe: mailto:oscar-unsubscribe@...
For general help: mailto:sympa@...?subject=help
ObjectWeb mailing lists service home page: http://www.objectweb.org/wws
LightInTheBox - Buy quality products at wholesale price!