Click here to Skip to main content
15,910,471 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Couple of scenarios.
If 2 separate classes receive the same data from the same file at about the same time, then change the data.

Scenario 1:
Class 1 is passed the data from an invoking class.
Class 2 is passed the same data from the same invoking class.
Both classes change the data and return it to the invoking class.

Scenario 2:
Classes 1 and 2 load the data at about the same time.
Class 1 saves, then class 2 saves.

What is the best way to avoid these situations?

What I have tried:

Created a god class to handle all the data loading, changing and saving. Not the best method and trying to find a better way.
Posted
Updated 4-Jun-16 4:31am
v2

The first thing that I came to think of was a mutex. Since you are talking about Java programming I will restrict myself to Java environment only.

Mutex are used in multithreading environments where multiple threads are going to perform actions on the same topic. This way, a simpler solution may be like this,
Java
// Save a flag
public static boolean writing = false;
public void write(BufferedWriter bw) {
   if(!writing) { // Or you may want to use a loop to wait for that thread.
      synchronized(bw) {
         writing = true;
         // Write the data to the file
      }
      writing = false;
   }
}

This way, you will have just one single object writing the data out to the file at the time. However, this would cause later threads to wait. An example program that I wrote just to clarify how you will be doing this is like this,

Java
// User object
public class User {
    public String name;
    public int age;
    
    public void write(int name) {
        System.out.println(String.valueOf(name) + " thread entered.");
        new Writer().write(this.name + ", " + String.valueOf(age), name);
        System.out.println(String.valueOf(name) + " thread leaving.");
    }
}

// Writer object; you can create a function that holds the thread
// I paused the thread instead of performing the task of writing. 
public class Writer extends OutputStream {
    
    public void write(String data, int number) {
        try {
            write(number);
        } catch (IOException ex) {
            Logger.getLogger(Writer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void write(int b) throws IOException {
        synchronized(this) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ex) {
                Logger.getLogger(Writer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

// Calling the functions, 
public static void main(String[] args) {
        User u1 = new User();
        User u2 = new User();
        
        u1.name = "Afzaal Ahmad Zeeshan";
        u2.name = "Afzaal Ahmad Zeeshan";
        u1.age = 20;
        u1.age = 20;
        
        u1.write(1);
        u2.write(2);
    }

Once this program generates the output it is like this,

1 thread entered.
1 thread leaving.
2 thread entered.
2 thread leaving.
// BUILD SUCCESSFUL (total time: 4 seconds)

It took 4 seconds because each thread took 2 seconds and until that was happening other threads were not allowed to perform anything on that object. Have a look at that, "synchronized (this)" which hold the object reference to itself.

multithreading - What is a mutex? - Stack Overflow[^]
https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html[^]
Lesson: Concurrency (The Java™ Tutorials > Essential Classes)[^]
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 4-Jun-16 10:39am    
I voted 4 this time.

This is all good, but you did not address the basic problems of this question. The inquirer did not even mention threads. The real problem is the lack of understanding of the basics, even the concept of objects (instances) — it's not about "classes", it's about instanced; shared objects are confused with static members and the singleton pattern. Yes, I understand that explaining the basics is much more difficult than known advanced issues.

I tried to explain it somehow and credited your solution; please see Solution 2.

—SA
Afzaal Ahmad Zeeshan 4-Jun-16 10:50am    
Thank you, Sergey.

Indeed, I missed those points out and yes, I was reading your solution before I could even read this comment of yours. Thank you for the credit, too.
The problem is unrelated to the concept of static member or singleton pattern. The problem is the problem of multithreading, the shared data, more exactly, access to the shared objects, and is solved via the mutual exclusion. You have to understand the essence of thread synchronization:
Mutual exclusion — Wikipedia, the free encyclopedia[^],
Critical section — Wikipedia, the free encyclopedia[^],
Synchronization (computer science) — Wikipedia, the free encyclopedia[^],
Race condition — Wikipedia, the free encyclopedia[^].

Solution 1 gives you an example of mutex use.

But your confusion stems from the lack of clear understanding what you are doing. First of all, you always talk about one or another class performing one or another action on the data. Classes are essentially irrelevant here; you should think of instances of classes, objects. If two instances work on the same (shared) objects concurrently, it does not matter if they are of the same class or different classes. However, you didn't mention the threads at all, so it's not clear if you even face the thread synchronization issues at all or not. It's not really clear what "about the same" may possibly mean, but it would be safer to assume you really do something in parallel.

Another problem is: you confuse static members and singletons with shared data.

If the object is shared, it does not matter if it is static member of some class or not. Likewise, it does not matter if singleton pattern is implemented or not. You simply share the reference to the same object in different parts of the code; this is all that matters. Actually, it's important to avoid static data by all means; and singleton, which is better, is also best avoided.

Even without static and without singleton, sharing of objects can be implemented, it this is needed, including the cases when it should be only one in the application runtime; you reach all the same goals related to the use of this object and face the same synchronization problems in case of concurrent use of it. Imagine the scenario: somewhere on the upper place of the execution stack, you create both objects accessing the data, the data class and pass the reference of the data class to both objects. As you need the mutex, you also create it in this code and pass the reference to the same objects. That's all.

And finally, let me note that "god object" is not even a pattern. It's a bad thing, a well-known anti-pattern of object-oriented programming. Please see:
God object — Wikipedia, the free encyclopedia[^],
Anti-pattern — Wikipedia, the free encyclopedia[^].

—SA
 
Share this answer
 
v2
Comments
Afzaal Ahmad Zeeshan 4-Jun-16 10:48am    
5ed.

You explained the answer in a much better and clearer way than I could have. However, I did wanted to mention the points of classes and objects but I missed. Nicely done. :-)
Sergey Alexandrovich Kryukov 4-Jun-16 10:52am    
Thank you, Afzaal.
I must say, explaining some basics is the awkward thing, not easy...
—SA
Afzaal Ahmad Zeeshan 4-Jun-16 11:01am    
Indeed.
Michael Hurt 4-Jun-16 12:05pm    
So talking about shared data and threads in java if I (Pseudocode)
public foo() {
var = 2
whatever(var)
}

Have I just passed a pointer for that memory location to whatever or have I just passed the data and created a new memory location assigned to whatever containing duplicate data? In thread terms, does the thread keep the same memory reference for var when it begins processing whatever?

Now if I
public whatever(int var) {
var = 1
file.save(var)
}

Do the threads processing foo now contain old data?
So now if I
public foo() {
var = idk
if (idk = 3) whatever(var)

bar(var)
}

Is bar now receiving outdated information? Are the foo threads that never enter whatever now using outdated data?
Sergey Alexandrovich Kryukov 4-Jun-16 13:41pm    
You should show where the shared objects are defined. What is it: var, file? what is idk?
The question is wrong, "is bar now receiving outdated information". This is the whole point: threads introduce indeterminism. Read the article on race condition, and you will understand it.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900