I'm in the process of converting our java code to use NIO, but I'm not sure of the best way to design it.
My initial approach was to create a pool of selector threads. The threads are started/killed as needed, and channels are registered to a selector thread when they are connected/accepted in a round-robin fashion. From there, each thread blocks on select(), and when woken up will run the appropriate callback associated with each channel that has a selected key.
In addition to this "multiple selector thread" design, I've also seen people say to use a single selector thread, and a pool of dispatch threads. When an IO operation is ready to be performed, the selector notifies a dispatcher thread, which then processes the request. This model has the benefit of not blocking the IO thread, but now we're forcing all of the IO into a single thread and dealing with synchronization/an event queue in the dispatcher.
Additionally I wouldn't be able to use a single direct byte buffer for reading each channel, passing it directly into the callback. Instead I'd have to copy the data out each time a read occurs into an array and reset. (I think..)
What's the best way to implement this?
Take a look at the Reactor Pattern
http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf
How you want your selectors to work really depends on your usecase. (Number of connections, message size, etc)
What is the problem that you are trying to solve by converting from IO to NIO?
You really should look into Mina,
http://mina.apache.org/
It solves all the problems you mentioned.
Also have a look at netty which is really fast and feature rich and also is used in big systems and by big companies like Redhat (jboss), Twitter, Facebook... .
Related
In my web application, we do some socket job in our servlet, and we log socket data into database.
I want to make that logging process asynchronous to improve performance.
My idea is using a separate dedicated thread to do the logging job. In my servlet, I just submit data to a cache, and let the logging thread to process them one by one.
I have a little experience in threading, What collection I can use as the cache ? What's the basic code pattern to implement this ? Please provide some code to show how to achieve that.
sorry for my poor English
As my application is legacy system running in production environment.It just use servlet and jsp no other Java EE technology. It seems that adding JMS support is too expensive for me.
A queue and a thread pool should be good.Publish your messages on a queue, let the workers thread pick messages from the queue and save them in database. Depending on your requirement/load, you may tune your queue and thread pool size.
If you're looking to output the log to a single file, you could try using a Semaphore (preferably a Mutex) on the logger class to prevent simultaneous writes / a race condition. Semaphores are synchronization primitives designed so that the programmer can use them to ensure only a certain number of accesses can be made to any one data structure at any one time. I won't explain the whole concept but Java provides these things in the java.util.concurrent.Semaphore class. A mutex (mutual exclusion lock) is a semaphore that only allows one thread to be "hold" it at any given time. Give it a try!
If you are looking at using a dedicated thread to handle the logging, you will want to implement a Producer/Consumer pattern, and use the Queue to handle the storing of the information objects. The producer/consumer pattern is mostly used to help with thread synchronization and communication. Here is an example of a Producer/Consumer implementation that might help: http://www.tutorialspoint.com/javaexamples/thread_procon.htm
The other option, is to generate a standard logging operation, and then create thread pool threads that do this work. The benefit of this is the thread pool handles the scheduling of the threads and when they execute, but the down side is that you are not guaranteed FIFO logging with this method since the thread scheduler can arbitrarily choose which thread in the pool to run next.
Unless your leader insists about reinventing the wheel, use slf4j with logback's DBAppender behind an AsyncAppender. It's ready out of the box, it works like a charm.
You should really read about logback's appenders.
A full example can be found here.
I want to generate some text string that is going to be sent via TCP socket . I have accomplished it within few minutes.
However I want a producer consumer pattern.I dont care if it failed or not.
Should I create a Blocking Queque at application for this ? Should I create a service ?
Note that I want a single thread to manage this job.
In the case it's a short task (like you commented), I'd recommend putting it within an AsyncTask as a background thread. You can control anything about this separately, which will help you also debugging it. Services are more intended for long executing tasks, so I'd not recommend it at this scope (it's a bit harder even to communicate with other Activity's. Here you'll find the AsyncTask's documentation, and here a good example.
The Blocking structure depends on your needs - but I don't think you'll need that in your case. Anyway, if you would need that, there're lots of thread-safe data structures you may use, you might find this helpful.
Create a LinkedBlockingQueue where your producer adds data. Create a Timer that fires every second or so. The task of the Timer would be to send the messages over the wire.
For this, both the producer (the one generating the messages) and consumer (Timer) should have access to the LinkedBlockingQueue. The Timer will remove the first element of the LinkedBlockingQueue and then send it.
Sounds good ?
I'm writing a server using java NIO, and I have a few questions that I can't find answers to.
First, regarding SSLEngine, how to handle NEED_TASK properly in separated thread? When I invoke tasks in separate thread they complete, but I have no idea how to go back to perform another handshake operation. One option would be to call that operation from a thread that was performing delegated task, but I guess that's not the way to do it.
Another question is about calling interestOps() from different thread then selector thread. I need to change key interests after an attempt to write to channel hadn't written all data.
I thought about using some sort of Queue of changes like in ROX NIO tutorial, but I have read in another thread here that it is not the best way.
first regarding SSLEngine, how to handle NEED_TASK properly in separated thread. When I invoke tasks in separate thread they complete, but I have no idea how to go back to perform another handshake operations.
While the engine is in NEED_TASK state it can't do anything else. When the task completes you should then repeat the operation that originally returned NEED_TASK and let the engine tell you what to do next. You need to block or disable use of that engine by other threads until the task completes, i.e. don't select on that channel.
Another question is about calling interestOps() from different thread then selector thread. I need to change key interests after an attempt to write to channel hadn't written all data. I thought about using some sort of Queue of changes like in ROX NIO tutorial, but I have read in another thread here that it is not the best way.
That would have been me. I hate those queues. I just wakeup() the selector and change the interestOps, never seen a problem with that. The selector thread has to cope correctly with zero keys being ready, but it already needs to do that.
I´ve a question concerning non blocking Sockets: I understand how to register for example, two socketchannels for write/read events.
But how does such an event look like? If I want to write some data on SocketChannel1 (for example when I press a button) to a server how can I do this?
All examples I´ve found only deal with the registration of the sockets, like this:
http://rox-xmlrpc.sourceforge.net/niotut/#About%20the%20author
Greetings,
Flo
I would look at the examples which come with the JDK under the sample directory.
If you use non blocking IO, you should wait until after you have a write op from the socket to perform the write. While you are waiting, you can buffer the data. However, this rarely needed as this is only required when the write buffer of the socket is full (which shouldn't happen very often) and if this is the case for a long period fo time you may deside you have a slow consumer and close the connection instead.
Personally, I wouldn't suggest you use non-blocking NIO directly unless you have a very good understanding of what is going on. Instead I suggest you use a library like Netty which will handle all the edge cases for you. Or you could use blocking NIO which is much simpler (and can be faster for a small number of connections)
I have an application that needs to read hundreds of socket communications.
I am using a ThreadPool, with a upper limit on the number of threads, to service these sockets. This causes blocking on all threads if the sockets do not have incoming messages.
I am currently using a soTimeout of 100ms to avoid a permanent blocking. I do not like this approach as it might timeout just as it starts receiving input.
Is there anyway other to approach this?
I tried checking with ObjectInputStream.isAvailable(), but that always returns 0, whether there is data in the stream or not.
I can't find any other way to check whether there is data on the stream. This would be ideal, as then I could check if there is data, if not then move on to next stream.
This is exactly the kind of problem NIO frameworks are meant to solve. Unfortunately, using raw NIO is a bit more difficult than using blocking IO. If you can, my recommendation would be to try out a framework like Netty which would ease the job for you.
You can give NIO a chance.
Use Selector and SocketChannels to wait for data instead of creating thread for each socket.
Selector
SocketChannel