Data acquisition and design patterns

I have to write a flexible data acquisition and control panel in Java. I'm not a Java
programmer. I have experience in LabVIEW and electronics design, hence my question is rather fundamental (if not stupid).

I have to choose proper design pattern to make my program scalable.

I want to control a data acquisition modules. My program will have multiple threads:
* 1 GUI thread to send commands to DAQ devices (buttons clickable by users + graphs)
* number of device control threads

At first it seems that Model-View-Controller pattern will fit. I don't know how
should I solve inter-thread communication to make it scalable and completely separate GUI and device control threads. I think about message queues (this is how we do such things in LabVIEW). Java offers event listeners, nofify(), blocking queues.

User press button 1 (1st device) and a message "measure stuff" is sent to 1st device control thread. Button should be locked until the device finishes the operation (1-10 seconds). When the device finishes, device control thread sends a message "finished". Button should be unlocked on this message. GUI should not be locked during measurement so 2 other devices can be triggered when the 1st one is busy.

My problem here is bi-directional communication. I don't want to clutter my code with
dozen of action listeners or mixing message queue with event listeners. I want to make it easy to add arbitrary number of devices without too much glue code.

What is the best practice to solve this kind of problem with scalability and code maintainability in mind?

MVC is definitely your best bet. You should have a minimum of three classes:

1. GUI class. This creates the GUI components and registers components to listeners. If you write ANY business logic in this class you know that something is wrong. There should only be visual components and components registering to listeners in this class only.

2. (one or more) Listener (controllers). The listener can take the action event, figure out which button was pressed, and then spawn off a thread that handles the device. You can have a boolean flag set in this class that determines whether or not a particular device is active. The GUI can access this variable to see if the button should remain active or disabled. The device threads can also set their corresponding boolean flag found in the controller.

3. Your models (the separate device threads). They do their own logic, and then set their corresponding boolean flag in the controller to tell everyone that they have finished.

As an alternative, you could also just do a subscriber model where each of the device threads simply notifies anyone who is subscribed that they are done.

You'll want to make sure you start your threads in the listener. Your listener can create the new classes that are Runnable. Other than that there shouldn't be a threading issue unless the different threads share common variables.

The methods that will set the boolean flags should be synchronized to avoid multithreading issues. Like this for example: