简体   繁体   中英

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?

10x in advance


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?

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.

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.

您可以在GameRank中引入同步方法,该方法将接受投票(+ ve或-ve)并相应地更新positiveVotes / negativeVotes。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM