You think about which objects need access to which information.
You have worker threads which need the connection details to connect the database. Okay. So you pass those in the constructor of the worker thread.
You have a manager thread which creates worker threads. Okay. So you pass the connection details in the constructor of the manager thread so you can pass them to the constructors of the worker threads.
Now, you will say you have too many things to pass through too many constructors.
Well, you don't have to pass the actual connection details. The manager thread needs to create worker threads, but it doesn't really care about the details, right? So you may find it more convenient - instead of passing all the worker thread parameters - to just pass a factory object.
// abstract class or interface.
// In this particular case you could also use java.util.function.Supplier<WorkerThread>
public abstract class WorkerThreadFactory {
public abstract WorkerThread createWorkerThread();
}
// and create the manager like this
ManagerThread manager = new ManagerThread(new WorkerThreadFactory() {
@Override
public WorkerThread createWorkerThread() {
return new WorkerThread(databaseConnectionDetails, otherStuffItNeeds);
}
});
// short version with a lambda expression
// note: I think this only works if WorkerThreadFactory is an interface
ManagerThread manager = new ManagerThread(() -> new WorkerThread(databaseConnectionDetails, otherStuffItNeeds));
Now, if you add more parameters to the worker threads, you don't need to update the manager class.
You could even go a step further and use this for the worker threads as well:
// instead of
new WorkerThread(hostname, port, username, password, databaseName)
// you could use
new WorkerThread(() -> connectToDatabase(hostname, port, username, password, databaseName))
// and now you don't have to pass 5 separate pieces of information into WorkerThread
Of course, I can't be more specific without seeing your code.
Yes, you could use static fields. Static fields are a cop-out for when you can't figure out how to structure your code this way. It's still bad design even if it's easy. (note that there's no problem with static methods, only static fields)
And this also applies to C. Global variables in C are considered bad, for the same reason static fields in Java are considered bad. One day you will want two managers connected to different databases and you will have to do it the hard way anyway.