I am runing into some difficulties in the interaction between my classes in my multithreaded application, my main chat server class first creates a DBConnection manager class and then creates a thread for each client connecting to my server. When the client connects I pass the connection to the client thread so that the client may interact with the DB and then return the connection to the pool when it is finished.
The problem occurs that if the connection to the DB drops there is no way for my client thread to re-establish the database connection pool as the only way it can re-initialise is talking to its 'super', now I cannot use the super statement as my clientThread extents Thread and not my main chatserver class. How can I solve this problem?
Delegation usually is a better design choice than inheritance. Foo has a Bar often gives you more options than Foo is a Bar.
my clientThread extents Thread
Don't do that. Your clientThread object should just be a plain Thread that is constructed with some ClientFoobar object that implements Runnable.
class Client implements Runnable {
private final DBConnectionManager dbConnectionManager;
private ...other state...
public Client(DBConnectionManager dbConnectionManager,...) {
this.dbConnectionManager = dbConnectionManager;
...
}
#Override
public void run() { ...interact with remote client... }
}
Thread clientThread = new Thread(new Client(dbConnectionManager,...)).start();
figured out how I can do it using some of your insight #james
I changed:
public class clientThread extends Thread {
}
To:
public class clientThread extends MultiThreadChatServer implements Runnable {
}
this allowed me to use my super class to reinitialise my connection pool when it drops the db connection.
In my Main class MultithreadChatServer I created a function to re-init the db connection (which is also called on the application start up) Now each of my threads will use a connection from the pool when they require (just need to make the pool big enough of course)
Related
I have a singleton class 'RealmDatabaseManager' where i have synchronized methods for reading/writing from realm local database.
The methods look like this:
public long getPendingImagesCount() {
synchronized (this) {
realm = Realm.getInstance(RealmUtils.getRealmConfiguration());
long count = realm.where(PatientRecordImage.class)
.count();
realm.close();
return count;
}
}
Where this is the instance of singleton class.
These methods are accessed from main as well as worker threads via the singleton instance. Every method creates and closes it's own realm.
The code works without issues on the devices i'm testing on but I've received Crashlytics reports from some devices giving two fatal errors.
IllegalStateException: Realm objects can only be accessed on the thread they were created.
And
IllegalStateException: Realm instance can only be closed on the thread it was created.
What is wrong with this approach? Can provide more info if needed.
Probably because you're setting the class variable to another Realm, and you have some fairly intricate multi-threading problem going on; nothing to do with device-specificness.
Solution: don't set the class level variable?
public long getPendingImagesCount() {
try(Realm realm = Realm.getInstance(RealmUtils.getRealmConfiguration())) {
return realm.where(PatientRecordImage.class).count();
}
}
if we look inside DefaultThreadFactory of Jgroups the following code is present
protected Thread newThread(Runnable r,String name,String addr,String cluster_name) {
String thread_name=getNewThreadName(name, addr, cluster_name);
Thread retval=new Thread(r, thread_name);
retval.setDaemon(createDaemons);
return retval;
}
As new thread is used so I believe in a managed server environment this can cause issues and is also not a good practice.
If I just replace the default thread factories and executors with Managed factories and executors of WebSphere will the behavior of Jgroups be still the same ?
Any pointers will be helpful ..?
Update
My intention is to use JGroups with WebSphere AS 8.5. I am keen to not have any un-managed threads. My main use case is for leader election and some message passing. It will be used to manage Spring Integration pollers and ensure only one poller is running within the cluster.
WAS 8.5 still uses the CommonJ api for Work management.
I am using Spring to abstract the Task Executors and Schedulers.
It was initially easy enough to replace the ThreadPools with task executors as they share the Executor api.
The TaskScheduler had to be adapted to work with your TimeScheduler interface.
They are very similar and perhaps extending from the ScheduledExecutorService could be an option here. I implemented to your interface and delegated to Springs TaskScheduler.
The main issue is with the ThreadFactory. CommonJ does not have this concept. For this I created a ThreadWrapper that encapsulates the Runnable and delegates out to a TaskExecutor when the "Thread's" start method is called. I ignored the thread renaming functionality as this will not have any effect.
public Thread newThread(Runnable command) {
log.debug("newThread");
RunnableWrapper wrappedCommand = new RunnableWrapper(command);
return new ThreadWrapper(taskExecutor, wrappedCommand);
}
public synchronized void start() {
try {
taskExecutor.execute(runnableWrapper);
} catch (Exception e) {
throw new UnableToStartException(e);
}
}
This is where I ran into problems. The issues were in the transports. In a number of cases with in the run method of some of the internal runnables e.g. the DiagnosticsHandler, the TransferQueueBundler of TP and ViewHandler of GMS there is a while statements that checks the thread.
public class DiagnosticsHandler implements Runnable {
public void run() {
byte[] buf;
DatagramPacket packet;
while(Thread.currentThread().equals(thread)) {
//...
}
}
}
protected class TransferQueueBundler extends BaseBundler implements Runnable {
public void run() {
while(Thread.currentThread() == bundler_thread) {
//...
}
}
}
class ViewHandler implements Runnable {
public void run() {
long start_time, wait_time; // ns
long timeout=TimeUnit.NANOSECONDS.convert(max_bundling_time, TimeUnit.MILLISECONDS);
List<Request> requests=new LinkedList<>();
while(Thread.currentThread().equals(thread) && !suspended) {
//...
}
}
}
This does not co-operate with our thread wrapping. If this could be altered so that the equals method is called on the stored thread it would be possible to override it.
As you can see from the various snippets there are various implementations and levels of protections varying from package, protected and public. This is increased the difficulty of extending the classes.
With all of this done it still did not remove completely the issue of unmanaged threads.
I was using the properties file method of creating the protocol stack. This initialises the protocol stack once the properties are set. To remove the Timer threads that are created by the bottom protocol. The TimeScheduler must be set prior the to stack being initialised.
Once this is done the threads are all managed.
Do you have any suggestions on how this could have been achieved more easily?
Yes, you can inject your on thread pools, see [1] for details.
[1] http://www.jgroups.org/manual/index.html#_replacing_the_default_and_oob_thread_pools
I am getting into ActiveJDBC at the moment, a very nice and useful framework, as far as I can tell. But I am having some problems with the JDBC-Connection management of it, as it attaches an opened connection to the current thread. That means, if I open the connection at the initialisation of my program, everything works fine; but if I instantiate a JFrame afterwards and try reading/wrtiting data from/to the database in an ActionListener for example, it will generate an error, since there is no connection attached to the dispatch thread.
How to solve this problem? I'd rather have just one connection, to which I can get access (via Base.connection()) all the time, instead of having one connection attached to each thread..
Thanks in advance
I would suggest that you implement action listener this way:
public class AJListenerAdapter implements ActionListener{
public void actionPerformed(ActionEvent e){
Base.open(...);
doPerform(ActionEvent e);
Base.close(...);
}
protected abstract doPerform(ActionEvent e);
}
then just subclass this adapter and implement the doPerform() method.
Additionally you might want to use connections from a pool. Here is an example
https://github.com/javalite/activejdbc/blob/master/activejdbc/src/test/java/org/javalite/activejdbc/C3P0PoolTest.java
I am working on a webserver written in Java. The web server is handling websocket communication with the clients and therefore we have a class called ClientHandler that has a socket and id as instance variables. The ClientHandler will need to have a function that will listen for messages from the clients. This function needs to work in paralell to the rest of the server, and since the "reading of messages" is a thread blocking function, we need a separate thread for this.
Here's the two alternative ways of implementing this:
public class ClientHandler implements Runnable{
//Instance variable
public Thread listener = new Thread(this);
.
.
.
public void run() {
while (!Thread.interrupted()){
//Listening code here
}
}
}
And then start the listener thread by writing
clientHandler.listener.start();
And stop it by writing
clientHandler.listener.interrupt();
Or this method:
public class ClientHandler {
//Instance variable
private Thread listenerTread;
private boolean alive; //set to true in constructor
.
.
.
public void listenToClient() {
listenerTread = new Thread(new Runnable() {
#Override
public void run(){
while (!alive){
//Listening code here
}
}
});
}
}
and then start the thread by calling the function listenToClient()
clientHandler.listenToClient();
and stop it by switching alive = false.
I have tried to find someone explaining the best solution, but most comparisons are between implementing Runnable or extending Thread. Is the any downsides to using either of the methods above? What method is best if I want to have multiple threads in one class?
I'm not sure you want to explicitly create a Thread instance. Why don't you try using a ThreadPoolExecutor to which you submit the tasks for execution. Read here more about thread pool. http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
Since you can have many clients, using a thread pool may improve the performance of your application.
You have two tasks. One is to listen for new connections and initiate serving of that connections. Second is to actually serve a connection. The decision to serve each connection within a separate thread is an implementation detail of the second task. In principle, it can be served in other ways, with a thread pool or with async IO. So this implementation detail should be hidden inside the code of the second task and must not be visible to the code of the first task. So use the second way.
I have a class that implements Runnable. For logging reasons I want to know the Thread that has been used to run the class. In that case would it be best to do
public class WebSocketHandle implements Runnable {
private Thread myThread; // access to thread for logging
public void start() {
myThread = new Thread(this);
myThread.start();
}
}
Then in the method that creates these I do something like:
public void newSocket(Socket socket)
{
WebSocketHandle handle = new WebSocketHandle(this, socket,_identity);
_sockets.add(handle);
EventLog.write("Socket assigned for new connection (" + _sockets.size() + ") " + handle.toString() + ". No value received yet yet...", getClass().getName(), "register");
// Start thread listening for data
new Thread(handle).start();
}
Or is it best to have something like:
public class WebSocketHandle implements Runnable {
private String myThread;
public void setThreadOwner(string threadId) {
myThread = threadId;
}
}
Then it would be used as such:
WebSocketHandle handle = new WebSocketHandle();
Thread newThread = new Thread(handle);
newThread.start();
handle.setThreadOwner(handle.toString());
I can't help but feel the second option is better practice but the code to write seems clumsier??
EDIT: In response to Aaron's comments:
This is for a Web server socket handling code so the Thread will be running indefinetly. I had not considered using ThreadPools so maybe that is something I need to consider
I log various activities (i.e. data received and sent) in the the WebSocketHandle class so I wanted to tie the logging events to the Thread instance that it is running on. To do that I found the easiest way was to log the thread.toString() as part of the log output.
You can simply call Thread.currentThread() to get the thread which is executing the code right now.
To help identifying a thread, use new Thread("some useful name");
[EDIT] Both of your approaches have some drawbacks. The first approach always creates a thread, so you can't execute the runnable in, say, a thread pool. And eventually, you will want to do that. Unfortunately, when you find out that you do, your application will have become very complex and it will be hard to change.
Also the "thread" doesn't help you much; it's usually irrelevant which thread started something. When looking for bugs, you want to know which piece of code executed a method. So it would make more sense to pass a Logger into start().
That said, what do you mean by "access to thread for logging"? What information does the anonymous thread created in start() contain which might be useful for logging? Since it has a generated name and you still don't know who called start(), the first approach looks completely useless to me.
The second approach allows you to give the Runnable a name but a) it doesn't compile and b) doesn't make any sense either (not mentioning the fact that the variable names are confusing).
To get the class of something, you can call getClass().getName(); there is no point in setting the class name of the instance using a setter. So the second approach is dangerously confusing and it violates the DRY principle.
Also, it doesn't give you much useful information for logging: It doesn't tell you who created the instance of MyClass and if you wanted a logger for MyClass, you can simply use this line:
private Logger log = LoggerFactory.getLogger(getClass());
There is no need for the setter.
So my conclusion is that both approaches should be avoided.