Parallel processing a Set - java

I have a Set of clients, and a Event I want to broadcast to them. To be more exact, I'm using CopyOnWriteArraySet to avoid ConcurrentModificationException.
It's all working nicely, but I'm beginning to hit a performance issue with large number of clients.
Could you suggest a way to serve the clients in parallel?
The broadcast loop now looks basically like this:
for (Client client : clients) {
sendTo(client, event);
}

With Java 8, you can replace the loop with:
clients.parallelForEach(client -> sendTo(client, event));
With Java 7, you will need to manually write the code. A first simple version would look like:
private final ExecutorService executor = new FixedThreadPool(N_THREADS);
private void send(Set<Client> clients, final Event event) {
for (Client client : clients) {
final Client c = client;
executor.submit(new Runnable() { public void run() { sendTo(c, event); }});
}
}

You may use threads using ExecutorService. Here's a kickoff example:
int MAX_THREADS = 10;
ExecutorSertive executor = Executors.newFixedThreadPool(MAX_THREADS);
for (final Client client : clients) {
executor.execute(new Runnable() {
#Override
public void run() {
//if event is a variable or a parameter in the bigger method
//mark it as final
sentTo(client, event);
}
});
}
executor.shutdown();

Related

How to start a thread only if it is not executing or not started before, or only one instance of thread should be created

I have the following method, that called every time I click over a button, this results to start a new thread again and again when the button is pressed, that results to multiple initialisation of thread, however I want only one thread should get executed, how can I achieve this.
private void scheduleMessages() {
new Thread(new Runnable() {
#Override
public void run() {
//Some operations
}
}).start();
}
Note: this is a small method and I don't want to create a separate class, just to make it singleton, so a solution without singleton pattern will be appreciated.
if you cannot make instance of this to check isActive() you should make a semaphore variable - a boolean, that you set to true when you start thread and set to false when you are done.
private void scheduleMessages() {
if (!taskRunning){
new Thread(new Runnable() {
#Override
public void run() {
taskRunning = true;
//Some operations
taskRunning = false;
}
}).start();
}
}
Have that thread be a background thread - maybe initialize it when the button is pressed the first time.
Have that thread listen to a queue - and act upon messages in that queue.
Whenever the button is pressed again, put a new message into the queue.
If your need to execute every requests but on a specific number of threads, you can use a thread pool and let the executor manage the queue .
private ExecutorService services;
private final static int POOL_SIZE = 1;
public MessagesService(){
services = Executors.newFixedThreadPool(POOL_SIZE);
}
public void scheduleMessages(Runnable r){
services.submit(r);
}
If you call addCall x times, x thread will be executed at the end but will never use more than the number of thread available in the pool. Here, 1 thread.
For a system that only accept one request, you can use the same approch but check the Future returned by a single thread executor. That way, you can check the status of the service.
private ExecutorService services;
private Future<?> lastCall;
public MessagesService() {
services = Executors.newSingleThreadExecutor();
lastCall = null;
}
public synchronized void scheduleMessages(Runnable r) {
if(!isScheduled()){
lastCall = services.submit(r);
}
}
public boolean isScheduled(){
return lastCall != null && !lastCall.isDone();
}
That way, the Runnable doesn't need to update a flag, which give a reusable solution.
Here is a sample of the Runnable to test these codes :
new Runnable() {
System.out.println("Running");
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}

How to make some asynch calls in a loop

In a loop i need to make some checks, performed actually in some another verticle. In each iteration of my loop i need to check the response code, returned from those verticle and make some decision accordingly. In some other words i need to stop the execution of my loop and somehow wait till asynch. call returns. But such execution stop violates the vert.x philosophy, which states that main thread execution should be never stopped. How can i do it in the scope of Vert.x? So far i don't know how to do this. Any suggestions/code samples/urls to smth. like a solution would b highly appreciated.
Thanks!
When working with Vert.x you need to think less in terms of loops, and more in terms of callbacks.
You should use eventBus to communicate between vertices.
Let's say that what you want is something similar to this pseudocode:
for (int i = 0; i < 4; i++) {
int result = getVerticleResult();
System.out.println(result);
}
So, just a very basic example
class LooperVerticle extends AbstractVerticle {
private int i = 4;
#Override
public void start() throws Exception {
doWork();
}
private void doWork() {
vertx.eventBus().send("channel", "", (o) -> {
if (o.succeeded()) {
System.out.println(o.result().body());
i--;
if (i > 0) {
doWork();
}
}
});
}
}
class WorkerVerticle extends AbstractVerticle {
#Override
public void start() throws Exception {
vertx.eventBus().consumer("channel", (o) -> {
// Generate some random number
int num = ThreadLocalRandom.current().nextInt(0, 9);
// Simulate slowness
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
o.reply(num);
});
}
}
To test:
public class EventBusExample {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new LooperVerticle());
vertx.deployVerticle(new WorkerVerticle());
}
}
I think you need to use FutureTask and store them in a Collection and use FutureTask.get() to retrieve the result when needed which is a blocking call.
It sounds like a use case for reactive steam processing.
In general such problem could be solved using 2 parties:
a producer that executes tasks and returns asynchronous results
a handler that subscribes to results and performs another tasks
There is a way to configure producer to perform tasks only when there is a subscriber. And on other side subscriber can decide to unsubscribe from producer on some condition.
I'm not familiar with vertx capabilities for reactive streams. But I would start from RxJava integration
http://vertx.io/docs/vertx-rx/java/

How to limit creation of Java objects?

I have an app, where I have some heavy objects, I want to limit the object creation to some x number (it won't affect my app). how to do it?
Modifying the Singleton pattern. You can use a count variable. You'll need to keep the Constructor private to have control over the no. of instances.
You could use Active Object Pattern, as an alternative to standard pool.
Since you need a couple of such objects, the objects probably maintain state.
Therefore you could have List of Active objects to which you dispatch requests via some proxy.
Idea is the following:
1) There is "scheduler", which in simplest form is a thread waiting on Blocking Queue and handle requests one by one. Notice how method run is executed, not thread.start().
2) You have blocking queue of services to which you dispatch requests which are picked up by the "scheduler" thread.
3) Your Active Object exposes services which are processed by Scheduler.
Next, you can wrap static list of these Active Objects behind some Proxy which would be responsible for delegating requests to your active objects, via round robin or whichever other balancing strategy.
Here is an example from wikipedia:
class BecomeActiveObject
{
private double val = 0.0;
private BlockingQueue<Runnable> dispatchQueue
= new LinkedBlockingQueue<Runnable>();
//
public BecomeActiveObject()
{
new Thread(
new Runnable()
{
#Override
public void run()
{
while (true)
{
try
{
dispatchQueue.take().run();
} catch (InterruptedException e)
{ // okay, just terminate the dispatcher
}
}
}
}
).start();
}
//
void doSomething() throws InterruptedException
{
dispatchQueue.put(
new Runnable()
{
public void run() { val = 1.0; }
}
);
}
//
void doSomethingElse() throws InterruptedException
{
dispatchQueue.put(
new Runnable()
{
public void run() { val = 2.0; }
}
);
}
}

How to send multiple asynchronous requests to different web services?

I need to send multiple requests to many different web services and receive the results. The problem is that, if I send the requests one by one it takes so long as I need to send and process all individually.
I am wondering how I can send all the requests at once and receive the results.
As the following code shows, I have three major methods and each has its own sub methods.
Each sub method sends request to its associated web service and receive the results;therefore, for example, to receive the results of web service 9 I have to wait till all web services from 1 to 8 get completed, it takes a long time to send all the requests one by one and receive their results.
As shown below none of the methods nor sub-methods are related to each other, so I can call them all and receive their results in any order, the only thing which is important is to receive the results of each sub-method and populate their associated lists.
private List<StudentsResults> studentsResults = new ArrayList();
private List<DoctorsResults> doctorsResults = new ArrayList();
private List<PatientsResults> patientsResults = new ArrayList();
main (){
retrieveAllLists();
}
retrieveAllLists(){
retrieveStudents();
retrieveDoctors();
retrievePatients();
}
retrieveStudents(){
this.studentsResults = retrieveStdWS1(); //send request to Web Service 1 to receive its list of students
this.studentsResults = retrieveStdWS2(); //send request to Web Service 2 to receive its list of students
this.studentsResults = retrieveStdWS3(); //send request to Web Service 3 to receive its list of students
}
retrieveDoctors(){
this.doctorsResults = retrieveDocWS4(); //send request to Web Service 4 to receive its list of doctors
this.doctorsResults = retrieveDocWS5(); //send request to Web Service 5 to receive its list of doctors
this.doctorsResults = retrieveDocWS6(); //send request to Web Service 6 to receive its list of doctors
}
retrievePatients(){
this.patientsResults = retrievePtWS7(); //send request to Web Service 7 to receive its list of patients
this.patientsResults = retrievePtWS8(); //send request to Web Service 8 to receive its list of patients
this.patientsResults = retrievePtWS9(); //send request to Web Service 9 to receive its list of patients
}
That is a simple fork-join approach, but for clarity, you can start any number of threads and retrieve the results later as they are available, such as this approach.
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Callable<String>> tasks = new ArrayList<>();
tasks.add(new Callable<String>() {
public String call() throws Exception {
Thread.sleep((new Random().nextInt(5000)) + 500);
return "Hello world";
}
});
List<Future<String>> results = pool.invokeAll(tasks);
for (Future<String> future : results) {
System.out.println(future.get());
}
pool.shutdown();
UPDATE, COMPLETE:
Here's a verbose, but workable solution. I wrote it ad hoc, and have not compiled it.
Given the three lists have diffent types, and the WS methods are individual, it is not
really modular, but try to use your best programming skills and see if you can modularize it a bit better.
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Callable<List<StudentsResults>>> stasks = new ArrayList<>();
List<Callable<List<DoctorsResults>>> dtasks = new ArrayList<>();
List<Callable<List<PatientsResults>>> ptasks = new ArrayList<>();
stasks.add(new Callable<List<StudentsResults>>() {
public List<StudentsResults> call() throws Exception {
return retrieveStdWS1();
}
});
stasks.add(new Callable<List<StudentsResults>>() {
public List<StudentsResults> call() throws Exception {
return retrieveStdWS2();
}
});
stasks.add(new Callable<List<StudentsResults>>() {
public List<StudentsResults> call() throws Exception {
return retrieveStdWS3();
}
});
dtasks.add(new Callable<List<DoctorsResults>>() {
public List<DoctorsResults> call() throws Exception {
return retrieveDocWS4();
}
});
dtasks.add(new Callable<List<DoctorsResults>>() {
public List<DoctorsResults> call() throws Exception {
return retrieveDocWS5();
}
});
dtasks.add(new Callable<List<DoctorsResults>>() {
public List<DoctorsResults> call() throws Exception {
return retrieveDocWS6();
}
});
ptasks.add(new Callable<List<PatientsResults>>() {
public List<PatientsResults> call() throws Exception {
return retrievePtWS7();
}
});
ptasks.add(new Callable<List<PatientsResults>>() {
public List<PatientsResults> call() throws Exception {
return retrievePtWS8();
}
});
ptasks.add(new Callable<List<PatientsResults>>() {
public List<PatientsResults> call() throws Exception {
return retrievePtWS9();
}
});
List<Future<List<StudentsResults>>> sresults = pool.invokeAll(stasks);
List<Future<List<DoctorsResults>>> dresults = pool.invokeAll(dtasks);
List<Future<List<PatientsResults>>> presults = pool.invokeAll(ptasks);
for (Future<List<StudentsResults>> future : sresults) {
this.studentsResults.addAll(future.get());
}
for (Future<List<DoctorsResults>> future : dresults) {
this.doctorsResults.addAll(future.get());
}
for (Future<List<PatientsResults>> future : presults) {
this.patientsResults.addAll(future.get());
}
pool.shutdown();
Each Callable returns a list of results, and is called in its own separate thread.
When you invoke the Future.get() method you get the result back onto the main thread.
The result is NOT available until the Callable have finished, hence there is no concurrency issues.
So just for fun I am providing two working examples. The first one shows the old school way of doing this before java 1.5. The second shows a much cleaner way using tools available within java 1.5:
import java.util.ArrayList;
public class ThreadingExample
{
private ArrayList <MyThread> myThreads;
public static class MyRunnable implements Runnable
{
private String data;
public String getData()
{
return data;
}
public void setData(String data)
{
this.data = data;
}
#Override
public void run()
{
}
}
public static class MyThread extends Thread
{
private MyRunnable myRunnable;
MyThread(MyRunnable runnable)
{
super(runnable);
setMyRunnable(runnable);
}
/**
* #return the myRunnable
*/
public MyRunnable getMyRunnable()
{
return myRunnable;
}
/**
* #param myRunnable the myRunnable to set
*/
public void setMyRunnable(MyRunnable myRunnable)
{
this.myRunnable = myRunnable;
}
}
public ThreadingExample()
{
myThreads = new ArrayList <MyThread> ();
}
public ArrayList <String> retrieveMyData ()
{
ArrayList <String> allmyData = new ArrayList <String> ();
if (isComplete() == false)
{
// Sadly we aren't done
return (null);
}
for (MyThread myThread : myThreads)
{
allmyData.add(myThread.getMyRunnable().getData());
}
return (allmyData);
}
private boolean isComplete()
{
boolean complete = true;
// wait for all of them to finish
for (MyThread x : myThreads)
{
if (x.isAlive())
{
complete = false;
break;
}
}
return (complete);
}
public void kickOffQueries()
{
myThreads.clear();
MyThread a = new MyThread(new MyRunnable()
{
#Override
public void run()
{
// This is where you make the call to external services
// giving the results to setData("");
setData("Data from list A");
}
});
myThreads.add(a);
MyThread b = new MyThread (new MyRunnable()
{
#Override
public void run()
{
// This is where you make the call to external services
// giving the results to setData("");
setData("Data from list B");
}
});
myThreads.add(b);
for (MyThread x : myThreads)
{
x.start();
}
boolean done = false;
while (done == false)
{
if (isComplete())
{
done = true;
}
else
{
// Sleep for 10 milliseconds
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public static void main(String [] args)
{
ThreadingExample example = new ThreadingExample();
example.kickOffQueries();
ArrayList <String> data = example.retrieveMyData();
if (data != null)
{
for (String s : data)
{
System.out.println (s);
}
}
}
}
This is the much simpler working version:
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadingExample
{
public static void main(String [] args)
{
ExecutorService service = Executors.newCachedThreadPool();
Set <Callable<String>> callables = new HashSet <Callable<String>> ();
callables.add(new Callable<String>()
{
#Override
public String call() throws Exception
{
return "This is where I make the call to web service A, and put its results here";
}
});
callables.add(new Callable<String>()
{
#Override
public String call() throws Exception
{
return "This is where I make the call to web service B, and put its results here";
}
});
callables.add(new Callable<String>()
{
#Override
public String call() throws Exception
{
return "This is where I make the call to web service C, and put its results here";
}
});
try
{
List<Future<String>> futures = service.invokeAll(callables);
for (Future<String> future : futures)
{
System.out.println (future.get());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
}
}
You can ask your jax-ws implementation to generate asynchronous bindings for the web service.
This has two advantages that I can see:
As discussed in Asynchronous web services calls with JAX-WS: Use wsimport support for asynchrony or roll my own? , jax-ws will generate well-tested (and possibly fancier) code for you, you need not instantiate the ExecutorService yourself. So less work for you! (but also less control over the threading implementation details)
The generated bindings include a method where you specify a callback handler, which may suit your needs better than synchronously get() ting all response lists on the thread calling retrieveAllLists(). It allows for per-service-call error handling and will process the results in parallel, which is nice if processing is non-trivial.
An example for Metro can be found on the Metro site. Note the contents of the custom bindings file custom-client.xml :
<bindings ...>
<bindings node="wsdl:definitions">
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
</bindings>
When you specify this bindings file to wsimport, it'll generate a client which returns an object that implements javax.xml.ws.Response<T>. Response extends the Future interface that others also suggest you use when rolling your own implementation.
So, unsurprisingly, if you go without the callbacks, the code will look similar to the other answers:
public void retrieveAllLists() throws ExecutionException{
// first fire all requests
Response<List<StudentsResults>> students1 = ws1.getStudents();
Response<List<StudentsResults>> students2 = ws2.getStudents();
Response<List<StudentsResults>> students3 = ws3.getStudents();
Response<List<DoctorsResults>> doctors1 = ws4.getDoctors();
Response<List<DoctorsResults>> doctors2 = ws5.getDoctors();
Response<List<DoctorsResults>> doctors3 = ws6.getDoctors();
Response<List<PatientsResults>> patients1 = ws7.getPatients();
Response<List<PatientsResults>> patients2 = ws8.getPatients();
Response<List<PatientsResults>> patients3 = ws9.getPatients();
// then await and collect all the responses
studentsResults.addAll(students1.get());
studentsResults.addAll(students2.get());
studentsResults.addAll(students3.get());
doctorsResults.addAll(doctors1.get());
doctorsResults.addAll(doctors2.get());
doctorsResults.addAll(doctors3.get());
patientsResults.addAll(patients1.get());
patientsResults.addAll(patients2.get());
patientsResults.addAll(patients3.get());
}
If you create callback handers such as
private class StudentsCallbackHandler
implements AsyncHandler<Response<List<StudentsResults>>> {
public void handleResponse(List<StudentsResults> response) {
try {
studentsResults.addAll(response.get());
} catch (ExecutionException e) {
errors.add(new CustomError("Failed to retrieve Students.", e.getCause()));
} catch (InterruptedException e) {
log.error("Interrupted", e);
}
}
}
you can use them like this:
public void retrieveAllLists() {
List<Future<?>> responses = new ArrayList<Future<?>>();
// fire all requests, specifying callback handlers
responses.add(ws1.getStudents(new StudentsCallbackHandler()));
responses.add(ws2.getStudents(new StudentsCallbackHandler()));
responses.add(ws3.getStudents(new StudentsCallbackHandler()));
...
// await completion
for( Future<?> response: responses ) {
response.get();
}
// or do some other work, and poll response.isDone()
}
Note that the studentResults collection needs to be thread safe now, since results will get added concurrently!
Looking at the problem, you need to integrate your application with 10+ different webservices.While making all the calls asynchronous. This can be done easily with Apache Camel. It is a prominent framework for enterprise integration and also supports async processing. You can use its CXF component for calling webservices and its routing engine for invocation and processing results. Look at the following page regarding camel's async routing capability. They have also provided a complete example invoking webservices async using CXF, it available at its maven repo. Also see the following page for more details.
You might consider the following paradigm in which you create work (serially), but the actual work is done in parallel. One way to do this is to: 1) have your "main" create a queue of work items; 2) create a "doWork" object that queries the queue for work to do; 3) have "main" start some number of "doWork" threads (can be same number as number of different services, or a smaller number); have the "doWork" objects put add their results to an object list (whatever construct works Vector, list...).
Each "doWork" object would mark their queue item complete, put all results in the passed container and check for new work (if no more on the queue, it would sleep and try again).
Of course you will want to see how well you can construct your class model. If each of the webservices is quite different for parsing, then you may want to create an Interface that each of your "retrieveinfo" classes promises to implement.
It has got various option to develop this.
JMS : quality of service and management, e.g. redelivery attempt, dead message queue, load management, scalability, clustering, monitoring, etc.
Simply using the Observer pattern for this. For more details OODesign and How to solve produce and consumer follow this Kodelog**

multithreading within vertx

I am a newbie to vert.x. I was trying out the vert.x "NetServer" capability. http://vertx.io/core_manual_java.html#writing-tcp-servers-and-clients and it works like a charm .
However , I also read that "A verticle instance is strictly single threaded.
If you create a simple TCP server and deploy a single instance of it then all the handlers for that server are always executed on the same event loop (thread)."
Currently, for my implementation, I wanted to receive the TCP stream of bytes and then trigger another component. But this should not be a blocking call within the "start" method of the Verticle. So, is it a good practice, to write an executor within the start method? or does vertx automatically handle such cases.
Here is a snippet
public class TCPListener extends Verticle {
public void start(){
NetServer server = vertx.createNetServer();
server.connectHandler(new Handler<NetSocket>() {
public void handle(NetSocket sock) {
container.logger().info("A client has connected");
sock.dataHandler(new Handler<Buffer>() {
public void handle(Buffer buffer) {
container.logger().info("I received " + buffer.length() + " bytes of data");
container.logger().info("I received " + new String(buffer.getBytes()));
//Trigger another component here. SHould be done in a sperate thread.
//The previous call should be returned . No need to wait for component response.
}
});
}
}).listen(1234, "host");
}
}
What should be mechanism to make this a non blocking call.
I don't think this is the way to go for vert.x.
A better way would be to use the event bus properly instead of Executor. Have a worker respond to the event on the bus, do the processing, and signal the bus when it's completed.
Creating threads defeats the purpose of going with vert.x.
The most flexible way is to create an ExecutorService and process requests with it. This brings fine-grained control over threading model of workers (fixed or variable number of threads, what work should be performed serially on a single thread, etc).
Modified sample might look like this:
public class TCPListener extends Verticle {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
public void start(){
NetServer server = vertx.createNetServer();
server.connectHandler(new Handler<NetSocket>() {
public void handle(final NetSocket sock) { // <-- Note 'final' here
container.logger().info("A client has connected");
sock.dataHandler(new Handler<Buffer>() {
public void handle(final Buffer buffer) { // <-- Note 'final' here
//Trigger another component here. SHould be done in a sperate thread.
//The previous call should be returned . No need to wait for component response.
executor.submit(new Runnable() {
public void run() {
//It's okay to read buffer data here
//and use sock.write() if necessary
container.logger().info("I received " + buffer.length() + " bytes of data");
container.logger().info("I received " + new String(buffer.getBytes()));
}
}
}
});
}
}).listen(1234, "host");
}
}
As duffymo mentioned creating threads defeats the purpose of using vertx. Best way would be to write a message into eventbus and create a new handler listening for messages from the eventbus. Updated the code to showcase this. Writing the messages to "next.topic" topic, and registered a handler to read message from "next.topic" topic.
public class TCPListener extends Verticle {
public void start(){
NetServer server = vertx.createNetServer();
server.connectHandler(new Handler<NetSocket>() {
public void handle(NetSocket sock) {
container.logger().info("A client has connected");
sock.dataHandler(new Handler<Buffer>() {
public void handle(Buffer buffer) {
String recvMesg = new String(buffer.getBytes());
container.logger().info("I received " + buffer.length() + " bytes of data");
container.logger().info("I received " + recvMesg);
//Writing received message to event bus
vertx.eventBus().send("next.topic", recvMesg);
}
});
}
}).listen(1234, "host");
//Registering new handler listening to "next.topic" topic on event bus
vertx.eventBus().registerHandler("next.topic", new Handler<Message<String>() {
public void handle(Message<String> mesg) {
container.logger.info("Received message: "+mesg.body());
}
};
}
}

Categories

Resources