Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Threads passing an object reference to static helper method

I am just a beginner in Java and have stumbled upon multi-threaded applications. I know this question is similar to some posts here but I couldn't find a better answer for my query. Basically, I want to pass an object to a static method and the method will just return an output based on the values/properties of the object. For every call, I am creating a new instance of the object and there is no chance in any way that I will modify the object inside the method. Now, my question is, will JVM create a new instance of the static method and its local variables into the Stack (excluding the object as it will be on the Heap) for every call by multiple threads? For a clear view of what I want to achieve, here is my code:

TestConcurrent.java

import classes.Player;

public class TestConcurrent
{
    private static int method(Player player)
    {
        int y = (player.getPoints() * 10) + 1;

            try {
                    Thread.sleep(1000);
            } catch (InterruptedException e) {}

            return ++y;
    }

    public static void main(String[] args) throws Exception
    {
        // Create 100 threads
        for(int i=1;i<=100;i++)
        {
            final int j = i;
            // Create a new Thread
            new Thread()
            {
                public void run()
                {
                    // Create a new instance of the Player class
                    Player player = new Player(j,j,"FirstName" + j, "LastName" + j);
                    // Call static method() and pass a new instance of Player class
                    System.out.println("Thread " + j + ": " + TestConcurrent.method(player));
                    // Check the values of the Player class after the call to the static method()
                    System.out.println("Player" + player.getAcctId() + " : Points=" + player.getPoints() + " Name=" + player.getFirstName() + " " + player.getLastName());
                }
            }.start();
        }
    }

}

Player.java

package classes;

public class Player
{
    private int acctId, points;
    String firstName, lastName;

    public Player(int acctId, int points, String firstName, String lastName)
    {
        this.acctId = acctId;
        this.points = points;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public int getAcctId() {
        return acctId;
    }
    public void setAcctId(int acctId) {
        this.acctId = acctId;
    }
    public int getPoints() {
        return points;
    }
    public void setPoints(int points) {
        this.points = points;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

OUTPUT:

Since I didn't put a synchronized keyword, the output will be different every time and it looks similar to the following: (output is correct and it is exactly what I am expecting, I just want to clarify that I am on the right path since I don't want to use synchronization as it will slow down the process because each thread will have to wait for the other thread to finish before it can call the static method)

Thread 2: 22
Player8 : Points=8 Name=FirstName8 LastName8
Thread 22: 222
Thread 26: 262
Thread 23: 232
Player23 : Points=23 Name=FirstName23 LastName23
Thread 21: 212
Player21 : Points=21 Name=FirstName21 LastName21
Thread 25: 252
Player25 : Points=25 Name=FirstName25 LastName25
Thread 20: 202
Thread 19: 192
Thread 24: 242
Player24 : Points=24 Name=FirstName24 LastName24
Player9 : Points=9 Name=FirstName9 LastName9
Thread 28: 282
like image 351
Popoy Makisig Avatar asked May 18 '12 06:05

Popoy Makisig


2 Answers

will JVM create a new instance of the static method and its local variables into the Stack (excluding the object as it will be on the Heap) for every call by multiple threads?

Yes, that's exactly right.

If a static method only refers to local variables, it is automatically thread safe. (In fact, this holds for non-static methods as well.)

Generally speaking though, I would say you should avoid static if possible. In general it makes code harder to test and to reason about due to the fact that static members are in a sense global.

like image 73
aioobe Avatar answered Nov 14 '22 22:11

aioobe


static methods are not a problem, only static variables will be shared across threads.

So two threads invoking

public static int sum(int a, int b) {
  int tmp = a + b;
  return tmp;
}

will not run into problems.

static int tmp;

public static int sum(int a, int b) {
  tmp = a + b;
  return tmp;
}

Will fail multi-threaded, because one thread may overwrite anothers tmp value.

Local variables, even in static methods, are still local and thus safe.

Using static methods is good. It highlights that the method does not require access to object variables. Using static non-constant variables is prone to errors, avoid this at all costs (and use synchronization on a constant if you need to access the variable).

like image 24
Has QUIT--Anony-Mousse Avatar answered Nov 14 '22 20:11

Has QUIT--Anony-Mousse