Java. Serializing objects in a multi-threaded environment

I have an object whose internal mutable state is constantly updated by one or more threads. The object is synchronized, and the goal is to periodically save its state (via serialization) from another thread:

public class Counter implements Serializable { private int dogCount; private int catCount; public synchronized void updateFromDogThread( int count ) { dogCount = count; } public synchronized void updateFromCatThread( int count ) { catCount = count; } } 

Questions:

  • Is serialization safe in this case?
  • How does it work under the hood? That is, will an ObjectOutputStream execute a serialization block until the threads no longer work on Counter ?
  • What to do if Counter Sync does not use the built-in lock, but some other lock?
+4
source share
3 answers
  • Is serialization safe in this case?

Not. As @Tom Hawtin says, you will need to do your own locking to ensure that objects (objects) will not be changed when they are serialized.

  • How does it work under the hood? That is, will an ObjectOutputStream execute a serialization block until the threads no longer run on the counter?

ObjectOutputStream does not block under the hood. This is necessary for the application, if necessary.

  • What if the counter synchronization does not use the built-in lock, but some other lock?

Then your application will also need to use this other lock to block updates when serialization occurs.

If the state you are serializing just consists of the state of one object with two fields, then blocking conflicts and granularity should not be a problem. But if the object is complex, then a blocking conflict can be problematic, like the problem of acquiring locks without risking a dead end. This scenario will require careful design.

+2
source

Whenever you need to change the serialization of a class, you must implement the special private method void writeObject(ObjectOutputStream) . ObjectOutputStream uses this method instead of the default algorithm.

In your case, you want serialization to be synchronized with the object. So all you have to do is add the synchronized keyword to the method. You can still use the default implementation of defaultWriteObject :

 private synchronized void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); } 
+3
source

This is not safe, but relatively easy to do so:

 synchronized (counter) { out.writeObject(counter); } 

As you noticed, a locked object is arbitrary, since the serialization mechanization mechanism knows how to get the corresponding lock. Even worse, the order of serialization and the graph of objects is also quite arbitrary, so any attempt to lock often leads to deadlocks. Even with the solution above, you are performing a complex operation inside the lock, so be careful with deadlocks.

+2
source

Source: https://habr.com/ru/post/1313281/


All Articles