Joro Seksa
Joro Seksa

Reputation: 1583

Where (exactly) should I use synchronization in my Java EE application

I am developing a content management system for game reviews using Java EE.

I have a very simple question and here it is:

I have an ArrayList with Game objects. Every game object has GameRank attribute which is a simple class defined like this:

public class GameRank 
{
    private int activity;
    private int positiveVotes;
    private int negativeVotes;


     public GameRank(int activity, int positiveVotes, int negativeVotes) 
     {
       this.activity = activity;
       this.positiveVotes = positiveVotes;
       this.negativeVotes = negativeVotes;   
     }
}

Visitors of the web site will have an option to vote positive or negative about the game and the result will be sent to the server using AJAX for example.

So the question is:

Where should I synchronize the access to the attributes of the GameRank objects - their getter and setter methods OR in the Controller Servlet that handles the users votes and based on the game id desides which object should be updated?


If I decide to use the synchronization inside the class I can use AtomicInteger as one of the posters suggested or this:

public class GameRank 
{
private volatile int activity;
private volatile int positiveVotes;
private volatile int negativeVotes;


public GameRank(int activity, int positiveVotes, int negativeVotes) 
{
    this.activity = activity;
    this.positiveVotes = positiveVotes;
    this.negativeVotes = negativeVotes;
    
    this.checkAndFixValues();
}

private void checkAndFixValues()
{
    if(this.activity < 1) this.activity = 1;
    if(this.positiveVotes < 1) this.positiveVotes = 1;
    if(this.negativeVotes < 1) this.negativeVotes = 1;
}

public int getActivity() 
{
    synchronized(GameRank.class)
    {
        return activity;
    }
}

public int getPositiveVotes() 
{
    synchronized(GameRank.class)
    {
        return positiveVotes;
    }
}

public int getNegativeVotes() 
{
    synchronized(GameRank.class)
    {
        return negativeVotes;
    }
}

public void incrementActivitiy()
{
    synchronized(GameRank.class)
    {
        activity++;
    }
}

}

Am I right?

Upvotes: 0

Views: 2848

Answers (3)

meriton
meriton

Reputation: 70564

In Java-EE (or in general when using servlets), different requests are handled by different threads. Wherever these threads operate on a shared object, you will need some kind of synchronization.

Depending on your persistence technology, that may or may not be the case. With JPA, it is common to give each thread its own persistence context, and detect conflicting updates in the database. If you do that, no synchronization within the JVM is needed, but you may need to implement retry logic in case a transaction can not commit due to a conflicting update. The same applies when using JDBC, provided you do not share JDBC objects (Connection, Resultset) across threads.

Upvotes: 3

Bohemian
Bohemian

Reputation: 424983

The problem with externalising responsibilities of being threadsafe is that other clients are free to ignore such concerns, corrupting all usage.

Better to internalize such concerns, and make your class threadsafe.

Fortunately, the JDK offers a class that does it all for you: AtomicInteger. If you change the type of your counters to AtomicInteger, you can simply add methods to increment them in a threadsafe way. See the javadoc of AtomicInteger for more.

Upvotes: 0

sudmong
sudmong

Reputation: 2036

You may introduce a synchronized method in GameRank, that method will accept the vote(+ve or-ve) and update positiveVotes/negativeVotes accordingly.

Upvotes: -1

Related Questions