I'm developing a program which does communication to different types of devices (with respective protocols). It should concurrently acquire messages from devices and write them to a file with specific format. Timing is very strict, therefore it's decided to be implemented as 2 threads - one getting messages from device and the second - writing them. The common object for both threads is a message queue.

There is a thread DeviceHandler, which starts acquisition thread DeviceDriver. In my opinion, messageQueue object should belong to DeviceHandler and is redundant to be at DeviceDriver and increases coupling. I decided to pass it to DeviceDriver's acquire method which should start this thread, but I don't know how to combine these both without making messageQueue an instance variable.

Moreover, since getting messages from devices is a big task, implementors of DeviceDriver use their own message requestors, which in turn should somehow get queue and actually fill it by messages. The same problem here. Also, due to implementation details, DeviceBDriverRequestor might be run as a thread.

class diagram

So I have questions:

  1. Am I right avoiding making messageQueue an instance variable of DeviceDriver? Or is it acceptable to have it everywhere?
  2. What would be a good way to implement DeviceDriver class (combination of run() and acquire(Queue messageQueue) methods) in a way I proposed?
  3. Are there maybe some good practices in dealing such situations?

Thank you in advance!

  • 3
    Questions containing words like "right," "good," "reasonable," and "acceptable" are not answerable unless you tell us specifically what those words mean within the context of your specific problem. In general, there is no "right" way; there is only the way that most effectively fulfills your specific requirements. – Robert Harvey Nov 10 '16 at 16:07

Unlike in C where you can't start a thread with multiple argument (pthread void** param :D), Java thread only permit to run the method run with no argument. (see https://stackoverflow.com/questions/877096 thanks @RobertHarvey).

You have no choice of using field to pass parameter to a Thread.

However you can decouple the DeviceDriver from its thread aspect, since on the abstract side, DevideDriver is not necesseraly one thread.

So you can move the method run() of DeviceDriver to a DeviceDriverThread and add a method run(MessageQueue queue) to DeviceDriver

This DeviceDriverThread will take as fields the MessageQueue and the concret DeviceDriver to run and this method run will do the following :

private MessageQueue queue;
private DeviceDriver deviceDriver;
public void run(){

I guess you will need the method stop in DevideDriverThread too.

Just think of it as a simple Adapter pattern.

  • @RobertHarvey exactly, i added the link, this is what I suggest that he can move away the thread aspect so he can have his DeviceDriver hierarchy not need a field but taking it as a parameter of the run() function (which is not anymore the one from Runnable interface). – Walfrat Nov 10 '16 at 16:07

Why don't you hide queue inside DeviceDriver and expose needed methods (get, clear, whatever) by thread-safe delegation?

This way the user of your DeviceDriver class won't care about it's realization and will only use what is actually needs, and your DeviceDriver won't have unnecessary dependence.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.