I'm developing a VOIP server on UDP using Netty. When a call is placed, I store a "call" object on a global list of calls, like this:
public final List<Call> calls = new ArrayList<Call>();
Every time i receive a response from a Call, i have to iterate through the list to find the right "call" then, use this call object to make decisions, maybe route the call to another place, etc.
My currently lazy solution to this threading problem is to use the synchronized key word over the whole list, every time I need to access the list OR the individual "call" objects. I know this is terrible but it's OK for a POC.
Now I need the do the right way. To the access the list, using a ConcurrentHashMap seems to be a good option, but my question is:
What is the proper way to lock and access individual "call" objects ?
I can have up to 4k simultaneous calls (500 packets/sec), could it be a problem to lock a lot of objects? What is the best solution to this?
Thanks in advance!
Do you need to lock the call objects from the outside? I am assuming that the call object is essentially 2 FIFO queues - one processing audio packets from caller1 to caller2, the second processing packets from caller2 to caller1. You can have methods that lock these queues internally (and individually) as they add/remove the "next" packet. Other than that, it seems like the data in the call object would be rather static through the life of the call. This also allows concurrent data processing for each direction of the call since any operation on a packet in one direction won't impact the other direction.
Related
I have an Actor that - in its very essence - maintains a list of objects. It has three basic operations, an add, update and a remove (where sometimes the remove is called from the add method, but that aside), and works with a single collection. Obviously, that backing list is accessed concurrently, with add and remove calls interleaving each other constantly.
My first version used a ListBuffer, but I read somewhere it's not meant for concurrent access. I haven't gotten concurrent access exceptions, but I did note that finding & removing objects from it does not always work, possibly due to concurrency.
I was halfway rewriting it to use a var List, but removing items from Scala's default immutable List is a bit of a pain - and I doubt it's suitable for concurrent access.
So, basic question: What collection type should I use in a concurrent access situation, and how is it used?
(Perhaps secondary: Is an Actor actually a multithreaded entity, or is that just my wrong conception and does it process messages one at a time in a single thread?)
(Tertiary: In Scala, what collection type is best for inserts and random access (delete / update)?)
Edit: To the kind responders: Excuse my late reply, I'm making a nasty habit out of dumping a question on SO or mailing lists, then moving on to the next problem, forgetting the original one for the moment.
Take a look at the scala.collection.mutable.Synchronized* traits/classes.
The idea is that you mixin the Synchronized traits into regular mutable collections to get synchronized versions of them.
For example:
import scala.collection.mutable._
val syncSet = new HashSet[Int] with SynchronizedSet[Int]
val syncArray = new ArrayBuffer[Int] with SynchronizedBuffer[Int]
You don't need to synchronize the state of the actors. The aim of the actors is to avoid tricky, error prone and hard to debug concurrent programming.
Actor model will ensure that the actor will consume messages one by one and that you will never have two thread consuming message for the same Actor.
Scala's immutable collections are suitable for concurrent usage.
As for actors, a couple of things are guaranteed as explained here the Akka documentation.
the actor send rule: where the send of the message to an actor happens before the receive of the same actor.
the actor subsequent processing rule: where processing of one message happens before processing of the next message by the same actor.
You are not guaranteed that the same thread processes the next message, but you are guaranteed that the current message will finish processing before the next one starts, and also that at any given time, only one thread is executing the receive method.
So that takes care of a given Actor's persistent state. With regard to shared data, the best approach as I understand it is to use immutable data structures and lean on the Actor model as much as possible. That is, "do not communicate by sharing memory; share memory by communicating."
What collection type should I use in a concurrent access situation, and how is it used?
See #hbatista's answer.
Is an Actor actually a multithreaded entity, or is that just my wrong conception and does it process messages one at a time in a single thread
The second (though the thread on which messages are processed may change, so don't store anything in thread-local data). That's how the actor can maintain invariants on its state.
In my app, I would receive some user data, putting them into an ArrayBlockingQueue, and then put them into a database. Here several threads are used for 'getting the data from the queue and putting it into database'. Then an issue came up.
The database is used to store each user's current status, thus the data's time sequence is very important. But when using multi threads to 'get and put', the order can not be ensured.
So I came up with an idea, it's like 'field grouping': for different users' data, multi-threads is fine, the order between them can be ignored; but each user's data must be retrieved by the same thread.
Now the question is, how can I do that?
Is the number of Users limited? Then you can simply cache a thread across each user.
// thread cache
Map<Sting, Thread> threadcache = new HashMap<String,Thread>();
threadcache.put("primary_key", t);
// when accessing the daya
Thread torun = threadcache.get(queue.peek());
torun.start();
else
Java thread takes name Thread.setName()/getName. Use that to identify a thread, still reuse is something you have to handle according to your business logic.
Try using PriorityBlockingQueue<E> . <E> should be comparable. Implement logic such that that each user's data is individually sorted as per required attributes. Also use threadpools instead of managing threads discretely .
I have created a number of threads. I know each threads name(suppose through an alien mechanism I set name of thread.) Now I am inside a thread and want to send a message to another thread.
I am trying to code a simulator of Pastry and Chord protocol. I can not have a number of distributed nodes, so I have created a number of threads. Now I want each thread send and receive messages from one another. I have set each nodes name as its IP(a randomly generated number). Now I do not know how to send a message from one node to another. Please tell me how to send a message from one thread to another if you know another threads name.
I would suggest some kind of a message system. The easiest way would be to create a thread-safe FIFO and pass it into each thread. If you want to send messages directly to each different thread, make a "Topic" for each thread.
Don't try to hack something in using the thread name, it'll just constrain you later.
Pasted from comment so I can parse it:
private static BlockingQueue[] queue;
private static int queueNum = 0;
public static void newQueue(String ip)
{
queue[queueNum] = new ArrayBlockingQueue(1024);
try{ queue[queueNum].put(ip); }
catch (InterruptedException e){e.printStackTrace(); }
queueNum++;
}
Oh, I see your problem. You never assign BlockingQueue a value. Try changing that line to:
private static BlockingQueue[] queue=new BlockingQueue[10];
That will allow you 10 queues.
I'd also suggest that instead of an array you use a HashMap so you can name, add and delete queues at will. Instead of being queue[2] you'll be addressing queue.get("Thread1Queue") or something more descriptive.
Note response to comments:
A HashMap can generally replace an array, it's lookup is nearly as quick but it uses anything for an index instead of numbers--Strings, enums, Objects, whatever you want (as long as it has the hash and equals methods overriden), but usually strings.
So if you are storing a bunch of queues, and you want to name them specifically, you can say:
HashMap queues=new HashMap();
queues.put("queue1", new ArrayBlockingQueue(1024));
queues.put("queue2",new ArrayBlockingQueue(1024));
...
Then whenever you want to access one you can use:
queues.get("queue1").put(new ThingToAddToArrayBlockingQueue())...
to put a "Thing to add" to queue1.
If you just want a "Bunch" of them and don't need to know which is which (Just a collection of threads that can be fed generic taskss) there are specific collections/patterns for that in the concurrent package.
The usual way to communicate between threads is by passing an object to each thread which then allows to communicate between them. Keep in mind that all fields and methods of that object which are accessed by more than one thread should be synchronized.
But when you want to simulate a network protocol, then why not go all the way and use network sockets for interprocess communication? Just make each thread listen to a different socket on 127.0.0.1.
If you want to send messages and then have them processed by other threads you need a shared object (queue, map etc.) into which threads can pump messages. Receiving threads must check for incoming messages, pull them and do the necessary processing.
I am making a 2 player videogame, and the oponent's position gets updated on a thread, because it has a socket that is continuously listening. What I want to share is position and rotation.
As it is a videogame I don't want the main thread to be blocked (or be just the minimum time possible) and I don't want the performance to be affected. So from what I've seen to share this info the normal thing to do would be something like
class sharedinfo
{
public synchronized read();
public synchronized write();
}
but this would block the read in the main thread (the same that draws the videogame) until the three values (or even more info in the future are written) are written, and also I've read that synchronized is very expensive (also it is important to say this game is for android also, so performance is very important).
But I was thinking that maybe having sharedInfo inside an AtomicReference and eliminating synchronized would make it more efficient, because it would only stop when the reference itself is being updated (the write would not exist, I would create a new object and put it on the atomicreference), also they say that atomic* use hardware operations and are more efficient than synchronized.
What do you think?
Consider using a queue for this, Java has some nice concurrent queue implementations. Look up the BlockingQueue interface in java.util.concurrent, and who implements it. Chances are you fill find strategies implemented that you hadn't even considered.
Before you know it, you will want to communicate more than just positions between your threads, and with a queue you can stick different type of objects in there, maybe at different priorities, etc.
If in your code you use Interfaces (like Queue or BlockingQueue) as much as possible (i.e. anywhere but the place where the specific instance is constructed), it is really easy to swap out what exact type of Queue you are using, if you need different functionality, or just want to play around.
In my program, I am essentially trying to connect to a publisher and get data. The basic functionality is there in these steps
I make the connection to the publisher with username and password etc
I make the request for data. Method exits
The publisher's API gives me a callback to a method onDataUpdate(Object theUpdate)
From there, I can print the data, or write it to a database or anything I need to do. That all works.
My problem is, I would now like to wrap the functionality in such a way that a calling program can say request the data and receive it as soon as I have it. Meaning, I want my exposed method to look like
public Object getData() {
subscribeForData();
// somehow wait
return theUpdate;
}
How can I make this happen? Is there some way I can use threads to wait/notify when I've received the update? I'm a newb to stackoverflow and also multithreaded programming, so any help and sample code would be much appreciated!! Thanks in advance.
In this case I would prefer to use CountDownLatch, where i'll initialize my lathch with count 1 as soon i subscribe for publisher i will call await() on latch and when i get the callback i'll countdown the latch.
Use a SynchronousQueue. Create it in getData, call put() in the callback method, then call take() in the original thread at the end of getData().
Check out CompletionService, especially ExecutorCompletionService. There is a nice example of a web page loader/renderer in the book Java Concurrency in Practice.
I'm not entirely certain about your question but I'll give it a shot - hope it helps :)
You could use a blockingqueue in java for this purpose (producer consumer message) - if you write to the queue when the callback gets invoked - from another thread, you could read from the queue. Blocking queues are thread safe (but may not fit your requirements).
You could also look into readwrite locks if you only have one thread writing to a collection and perhaps multiple readers (or even just on reader).
You could also look into the observer pattern - for reference: http://www.vogella.com/articles/DesignPatternObserver/article.html
If neither of those work, one could look into using a queue/topic from an in-VM messaging server such as ZeroMQ/ActiveMQ or perhaps something like Redis/HazelCast.
Hope it helps and good luck
Converting a asynchronous call to a synchronous one is an interesting exercise, I use it often in interviews (and the reverse, wrapping a synchronous call in asynchronous).
So there is a requestData method that is going to return immediately and it (or something else) will later call onDataUpdate in a different thread. You want to create a new method, say requestDataSynchronous that does not require the caller to use a callback but instead blocks till data is available and returns it to the caller.
So what you need for requestDataSynchronous to do is:
call requestData
wait till onDataUpdate is called (in a different thread)
get the data onDataUpdate received
return it to the caller
Of the above, #2 and #3 have to be done by some mode of inter-thread-communication. You can use wait/notifiy but it might be much simpler to use a BlockingQueue. onDataUpdate writes to it once data is available, and requestDataSynchronous reads from it, blocking on the read until onDataUpdate writes into it.
Using ExecutorService might make this even easier, but it will be useful to know what's going on.