Is there a way to stabilize the direct connection between threads in java?

We have a system in which each thread (maybe tens of them) works as a separate agent. It has its own internal variables and objects, and it controls the objects of other threads, as well as its own) to make decisions. Unfortunately, the system quite often comes to a standstill.

Looking through the java tutorial (http://download.oracle.com/javase/tutorial/essential/ concurrency / index.html) and through other topics here in stackoverflow, I managed to avoid some of these deadlocks by synchronizing the methods and using the monitor, how in:

Producer-> Monitor-> Consumer.

However, not all communications between threads can be modeled this way. As I mentioned earlier, at the moment, one thread must have access to the objects (variables, lists, etc.) of other threads. The way this is done now is that each thread has a list with pointers to each other thread, forming a network. By going through this list, one thread can read all the information it needs from all the others. Despite the lack of a record (there should not be any problems with data corruption), it still blocks.

My question is: is there already a known way to solve this problem? A standard template such as a monitor solution? Please let me know if the question needs a more detailed explanation and I will edit the message.

Thank you in advance!

-Edit ----

After receiving these answers, I studied more about java.concurrency, as well as the actor model. At the moment, the problem seems to be fixed by using a reentrant lock:

http://download.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

Since he may back away from trying to acquire locks, he seems to have no problem waiting for them forever. I also began to introduce an alternative version, following the actor’s model, as this seems like an interesting solution for this case.

My main mistakes were:

-Enable Trusted Sync

-When the textbook says that “the lock is on the object”, what they really mean is the whole object that executes the thread (in my case), and not the object that I would like to access.

Thank you all for your help!

+4
source share
6 answers

Look at higher level concurrency constructors such as the java.util.concurrent package and the Akka Structure / Library . Manual synchronization and locking is a guaranteed way to crash threads in Java.

+4
source

When one thread needs to synchronize with many other threads in such a way that a deadlock can occur, it is eager to get all your resources, and if you cannot get one resource from the set, release all resources and try again.

This is an algorithm based on the problem of dining philosophers .

+3
source

I would recommend applying the Actor model here (view share nothing parallelism model ).

Using this model means that your entire stream does not interrupt each other, and you do not need to perform any synchronization at all.

Instead of synchronizing you will use messages. When one Actor (stream) needs to receive information about another Actor, it simply asynchronously sends a corresponding message to this Actor.

Each actor can also respond to certain types of messages. So, when a new message arrives, the Actor analyzes it and sends a response (or does any other action). The key point here is that incoming messages are processed synchronously (i.e., this is the only point where you need the easiest way to synchronize), just mark the method that processes messages using the synchronized modifier).

+3
source

It is important to remember that you need to have all locks in sequential order in all of your threads in order to avoid the following situation:

 Thread 1 Thread 2 acquire A acquire B acquire B acquire A 

One way to do this is to have only objects that are used as locks that can be ordered.

 class Lock { static final AtomicLong counter = new AtomicLong() final long id = counter.incrementAndGet(); } 

which should be used as

 if (lock1.id < lock2.id) { synchronized (lock1) { synchronized (lock2) { ... } } } else { synchronized (lock2) { synchronized (lock1) { ... } } } 

Obviously, this will become tedious in the near future, in particular, more locks. Using explicit ReentrantLocks can help, since it more easily allows all of these things to be factored into the general method of capturing multiple locks.

Another strategy that may be applicable to your problem would be manual blocking. Consider

 class Node { final ReentrantLock lock = new ReentrantLock(); Node previous; Node next; } 

with a workaround like

 Node start = ...; Node successor; start.lock.lock(); try { successor = start.next; successor.lock.lock(); } finally { start.lock.unlock(); } // Here, we own the lock on start next sibling. We could continue // with this scheme, traversing the entire graph, at any time holding // at most two locks: the node we come from and the node we want to // go to. 

The above diagram still requires the locks to be received in sequential order across all threads. This means that you can only cross each graph in the forward direction (i.e., after the stream of next pointers) or backward (through previous ). Once you start using randomly, everything again becomes prone to deadlocks. This is also potentially true if you arbitrarily make changes to the chart structure by changing the positions of the nodes.

+2
source

How about an actor model ? In short, in actor programming, all threads work as independent participants (or, as you said, agents). Communication is through messages. Each actor has its own message queue and processes these messages one by one. This model is implemented in the Scala programming language, and one of its frameworks, Akka , can be used from Java.

0
source

I use ExecutorServices for each thread pool. If you want another thread to do the work, you give it copies (or immutable data) of all the information it needs. So you have a state that is local to the thread or thread pool, and you have information that is being transferred to another thread. those. you never pass mutable state to another thread. This avoids the need to block other stream data.

0
source

All Articles