I am working on an IoT project where devices send data to our Java Application called Gateway Adapter (GA).
In java I am using Thread Pool to start a new thread for every message we received from devices.
I have following code for Thread Allocator and Runnable Thread.
public class ThreadAllocator {
/** The thread pool. */
private ExecutorService executorService = Executors.newWorkStealingPool(1000);
public void allocateThread(IoSession session, String message) {
LOGGER.info("Entering allocateThread");
executorService.execute(new HelperThread(null,session, message));
}
}
public class HelperThread implements Runnable {
private String message;
public HelperThread(String message) {
LOGGER.info("Entering HelperThread");
this.message = message;
}
public void run() {
LOGGER.info("Entering run");
// Process Message
}
}
With above code when i did a load testing by sending around 5000 messages, I could see messages "Entering allocateThread" and "Entering HelperThread" 5000 times in log file but my run method executed only 1000 times means message "Entering run" was there in log file only 1000 times. Due to which other 4000 messages could not processed.
Is it the expected behavior "newWorkStealingPool" Thread Pool? Will it only execute tasks equals to number provided in its constructor? E.g. Executors.newWorkStealingPool(1000);
Kindly suggest the solution?
Am i missing some configuration or it is not the correct Thread Pool for my scenario? Then which Thread Pool will work correctly in this case?
Really appreciate your help.
Regards,
Krishan
Related
I am working on a scenario as described below:
We are consuming messages from kafka, and each message received should be processed in parallel, given that I have to keep on hold the main( or calling) thread until all the messages received(1 message-1 thread) are done with processing.
Given that number of messages is known and is available from the kafka message headers.
Once the processing is completed for all the threads, only after that the calling thread should proceed ahead.
I tried using CountDownLatch with the count as number of messages going to be received, but using this, it is keeping the main thread on hold, and not allowing to consume the next messages.
Is there anyway, by which this can be achieved ?
Code Snippet:
class MessageHandler{
#Autowired private ProcessorAsync processorAsync;
public void handle()
{
CountdownLatch countdown = new CountdownLatch(noOfMessages);
CompletableFuture<Void> future = processorAsync.processMessage(message,countdown);
countdown.await();
if(future.isDone())
{//post msg processing methods/api calls
m1();
m2();
}
}
}
class ProcessorAsync
{
#Async("customThreadPool") // max 20 threads
public CompletableFuture<Void> processMessage(Message msg, CountdownLatch countdown)
{
//DB update statements
// .
countdown.countdown();
return CompletableFuture.allOf();
}
}
I have a JMS application which tries to read from a JBosss Queue. I implemented MessageListener on my class and used the onMessage() to receive messages
public class JBossConnector implements MessageListener, AutoCloseable {}
Here is my method:
/**
* The listener method of JMS. It listens to messages from queue: 'jbossToAppia'
* If the message is of type MessageObject, then transfer that to Appia
*
* #param message JMS Message
*/
#Override
public void onMessage(Message message) {
// receive the message from jboss queue: 'jbossToAppia'
// then post it to appia
if (message instanceof ObjectMessage) {
try {
MessageObject messageObject = (MessageObject) ((ObjectMessage) message).getObject();
System.out.printf("JbossConnector: MessageObject received from JBOSS, %s\n", messageObject.getMessageType());
component.onMessageFromJboss(properties.getProperty("target.sessionID"), messageObject);
} catch (MessageFormatException exception) {
logger.error(ExceptionHandler.getFormattedException(exception));
ExceptionHandler.printException(exception);
} catch (JMSException exception) {
ExceptionHandler.printException(exception);
restart();
}
} else {
System.out.printf("%s: MessageFormatException(Message is not of the format MessageObject)\n", this.getClass().getSimpleName());
}
}
Whenever I find a JMSException I try to restart JBoss connection (Context, Connection, Session, Receiver, Sender). What my doubt is that I've read onMessage() uses multiple threads to receive messages from queue (correct me if I'm wrong).
When the JBoss queue connection severs, there would be at least some queues that throw this exception. That means they all will try to restart() the connection which is a waste of time (restart() first closes all the connections, sets the variables to null and then attempt to initiate connections).
Now I could do something like
synchronized (this){
restart();
}
or use volatile variables. But that would not guarantee that other threads won't attempt to restart() when current threads finishes the restart() operation (again correct me if I'm wrong).
Is there any solution to make this work?
The onMessage() of a MessageListener is indeed run from its own thread so you'll need proper concurrency controls. I think the simplest solution would just be to use a java.util.concurrent.atomic.AtomicBoolean. For example, in your restart() method you could do something like this:
private void restart() {
AtomicBoolean restarting = new AtomicBoolean(false);
if (!restarting.getAndSet(true)) {
// restart connection, session, etc.
}
}
This will make the restart() method effectively idempotent. Multiple threads will be able to call restart() but only the first thread which calls it will actually cause the resources to get re-created. All other calls will return immediately.
First of all, yes I looked up this question on google and I did not find any answer to it. There are only answers, where the thread is FINISHED and than the value is returned. What I want, is to return an "infinite" amount of values.
Just to make it more clear for you: My thread is reading messages from a socket and never really finishes. So whenever a new message comes in, I want another class to get this message. How would I do that?
public void run(){
while(ircMessage != null){
ircMessage = in.readLine();
System.out.println(ircMessage);
if (ircMessage.contains("PRIVMSG")){
String[] ViewerNameRawRaw;
ViewerNameRawRaw = ircMessage.split("#");
String ViewerNameRaw = ViewerNameRawRaw[2];
String[] ViewerNameR = ViewerNameRaw.split(".tmi.twitch.tv");
viewerName = ViewerNameR[0];
String[] ViewerMessageRawRawRaw = ircMessage.split("PRIVMSG");
String ViewerMessageRawRaw = ViewerMessageRawRawRaw[1];
String ViewerMessageRaw[] = ViewerMessageRawRaw.split(":", 2);
viewerMessage = ViewerMessageRaw[1];
}
}
}
What you are describing is a typical scenario of asynchronous communication. Usually solution could be implemented with Queue. Your Thread is a producer. Each time your thread reads a message from socket it builds its result and sends it into a queue. Any Entity that is interested to receive the result should be listening to the Queue (i.e. be a consumer). Read more about queues as you can send your message so that only one consumer will get it or (publishing) means that all registered consumers may get it. Queue implementation could be a comercialy available products such as Rabbit MQ for example or as simple as Java provided classes that can work as in memory queues. (See Queue interface and its various implementations). Another way to go about it is communication over web (HTTP). Your thread reads a message from a socket, builds a result and sends it over http using let's say a REST protocol to a consumer that exposes a rest API that your thread can call to.
Why not have a status variable in your thread class? You can then update this during execution and before exiting. Once the thread has completed, you can still query the status.
public static void main(String[] args) throws InterruptedException {
threading th = new threading();
System.out.println("before run Status:" + th.getStatus());
th.start();
Thread.sleep(500);
System.out.println("running Status:" + th.getStatus());
while(th.isAlive()) {}
System.out.println("after run Status:" + th.getStatus());
}
Extend thread to be:
public class threading extends Thread {
private int status = -1; //not started
private void setStatus(int status){
this.status = status;
}
public void run(){
setStatus(1);//running
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
setStatus(0); //exit clean
}
public int getStatus(){
return this.status;
}
}
And get an output of:
before run Status:-1
running Status:1
after run Status:0
I have a javax.jms.Queue queue and have my listener listening to this queue. I get the message(a String) and execute a process passing the string as an input parameter to that process.
I want to just run 10 instances of that process running at one time. Once those are finished then only next messages should be processed.
How it can be achieved? As it reads all the message at once and runs as many instances of that process running, causing the server to be hanged.
// using javax.jms.MessageListener
message = consumer.receive(5000);
if (message != null) {
try {
handler.onMessage(message); //handler is MessageListener instance
}
}
Try to put this annotation on your mdb listener:
#ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10")
I am assuming that you have a way of accepting hasTerminated messages from your external processes. This controller thread will communicate with the JMS listener using a Semaphore. The Semaphore is initialized with 10 permits, and every time an external process calls TerminationController#terminate (or however the external processes communicate with your listener process) it adds a permit to the Semaphore, and then JMSListener must first acquire a permit before it can call messageConsumer.release() which ensures that no more than ten processes can be active at a time.
// created in parent class
private final Semaphore semaphore = new Semaphore(10);
#Controller
public class TerminationController {
private final semaphore;
public TerminationController(Semaphore semaphore) {
this.semaphore = semaphore;
}
// Called from external processes when they terminate
public void terminate() {
semaphore.release();
}
}
public class JMSListener implements Runnable {
private final MessageConsumer messageConsumer;
private final Semaphore semaphore;
public JMSListener(MessageConsumer messageConsumer, Semaphore semaphore) {
this.messageConsumer = messageConsumer;
this.semaphore = semaphore;
}
public void run() {
while(true) {
semaphore.acquire();
Message message = messageConsumer.receive();
// create process from message
}
}
}
I think a simple while check would suffice. Here's some Pseudocode.
While (running processes are less than 10) {
add one to the running processes list
do something with the message
}
and in the code for onMessage:
function declaration of on Message(Parameters) {
do something
subtract 1 from the running processes list
}
Make sure that the variable you're using to count the amount of running processes is declared as volatile.
Example as requested:
public static volatile int numOfProcesses = 0;
while (true) {
if (numOfProcesses < 10) {
// read a message and make a new process, etc
// probably put your receive code here
numOfProcesses++;
}
}
Wherever your the code for your processes is written:
// do stuff, do stuff, do more stuff
// finished stuff
numOfProcesses--;
I need to be able to 'send' a string from one thread to 1 or more other threads. But I have no idea how to do this.
Basically, I have a server who has one connection that sends commands to it. I need to send these commands to all the other threads, so they can send them to their clients.
How can I have a single string that is referenced by all the other threads. How to know when all the threads executed the command string?
Somewhere you will need a List of your Runnabless like:
List<MyRunnable> runningThreads;
Then you will have an implementation of Runnable:
class MyRunnable implements Runnable {
public void run() { ... }
}
Now you need to have some way of sending a message to that Runnable.
class MyRunnable implements Runnable {
public void run() { ... }
public void sendMessage( String message ){ ... }
}
So to send all the runnable a message it's as easy as:
for( MyRunnable runnable : runningThreads ){
sendMessage( "Hello There!" );
}
What to do now depends heavily on what you want to do next with the message. In any way it has to appear somehow in the Thread's visible range. So for starters lets save it in a variable:
class MyRunnable implements Runnable {
private volatile String myLastMessage;
public void run() { ... }
public void sendMessage( String message ){
this.myLastMessage = message;
}
so if you're run is already run periodically you can get off with:
public void run(){
while( true ){
Thread.sleep( 1000 ); //1s
if( lastMessage != null ){
doSomethingWith( lastMessage );
lastMessage = null;
}
}
}
If you need more than one message stored in the Thread you can use e.g. SynchronizedList for this.
If you need your Thread to react instantly on the message it received then use a monitor and
notifyAll method. See e.g. here: http://www.programcreek.com/2009/02/notify-and-wait-example/
If I understand you right, this is your setup:
How can I have a single string that is referenced by all the other threads?
When the string is sent via sockets or similar, it will be a different string. But with the same content, and that's what counts here. So I would not care too much about this point.
How to know when all the threads executed the command string?
Have each thread sent back a confirmation to the server whenever the thread finished processing a command for all clients. The server keeps track of all commands sent and confirmations received.
Keep in mind, that threads may crash, connections may break and the execution of a command may not succeed in a timely fashion, or fail entirely.
Perhaps you are refering to the Observer pattern (aka, Publish–subscribe pattern). The server (publisher) needs to know their clients (subscribers) in order to send a common message, so you need a data structure. There are several ways to implement this. See the next links:
Observer pattern with threads
The concurrent implementation of a publisher/subscriber pattern
Chaining of observer/observable pattern