What is the best way to make bundles run parallel, threaded, in OSGI
java, multithreading, osgi
Solution
The 'problem' is that OSGI doesn't really support multithreading. Every bundle running on the same JVM just runs in 1 Thread, so it follows a synchronous model.
Sorry, but this is a total misunderstanding. Let me quote from OSGi Core specification, section 4.2.7:
The OSGi Framework is running in a multi-threaded environment. After the framework is started, it will start bundles and these bundles will be activated. Activated bundles normally start background threads or react on events from other bundles. That is, after the start method returns, the framework has moved to the ACTIVE state and many bundles can be busy on different threads.
In other words, you are free to create any threading solution that fits your needs. It is not an OSGi issue.
UPDATE:
Your service implementations could share an ExecutorService like this:
public class BServiceImplementation implements BService {
private ExecutorService executorService;
private CService cservice;
public void bindCService(CService service) {
cservice = service;
System.out.println("bundle gateway bound to b service");
}
public void bindExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}
public void unbindCService(CService service) {
this.cservice = null;
}
public void transmitIn(final int id) {
executorService.submit(new Runnable() {
@Override
public void run() {
process(id);
}
});
}
public void process(int id) {
// Lots of processing happens here
}
}
Then just have another bundle expose a ThreadPoolExecutor as an ExecutorService.
Problem
I'm working with the OSGI framework to make an application that heavily relies on processing of packages of data. Every bundle processes a package and then sends it to the next. What I want is that every bundle works parallel. So I want to make every bundle run in it's own Thread or multiple Threads. The 'problem' is that OSGI doesn't really support multithreading. Every bundle running on the same JVM just runs in 1 Thread, so it follows a synchronous model. My thoughts: So the nature of the application is kinda producer consumer like. Bundle A offers a service with a method that is used to send a package to A, let's call it method ain. Bundle B has a likewise setup, and so does C. They all have a a/b/cout method, in this method they use the service of the next bundle so in A.aout you would call bin like this: bservice.bin(package). So every bundle is a consumer and a producer of data packages, this leads me to think that using ExecutorService and BlockingQueues might work, but I'm not quite sure how to implement this 'correctly' between bundles, and with all of them being both Consumer and Producer I'm not quite sure if this is the best way to go around this problem. I hope you guys can help and/or have any suggestions. -- EDIT -- Bundle A AServiceImplementation ``` public class AServiceImplementation implements AService { private BService bservice; public void bindBService(BService service) { bservice = service; System.out.println("bundle gateway bound to b service"); } public void unbindBService(BService service) { this.bservice = null; } public void process(int id) { bservice.transmitIn(id); } } ``` Bundle B BServiceImplementation ``` public class BServiceImplementation implements BService { private CService cservice; public void bindCService(CService service) { cservice = service; System.out.println("bundle gateway bound to b service");; } public void unbindCService(CService service) { this.cservice = null; } public void transmitIn(int id){ // So if I would implement it THIS is where I would assign the data to // a thread to get it processed in the process method. // but doesn't that make THIS method, transmitIn a bottleneck since all packages // need to pass through here? process(id); } public void process(int id) { // Lots of processing happens here } } ``` I don't really understand how to make it that for example bundle A transmits the data to bundle B through the transmitIn method without transmitIn being a bottleneck, since I'd make my 'workdistribution' to different threads in that method (as seen in the code above)