多线程传递一个对象引用静态辅助方法(Multiple Threads passing an obje

2019-09-17 08:18发布

我只是在Java初学者,在多线程应用程序都有所涉猎。 我知道这个问题是类似于此的一些职位,但我找不到我的查询一个更好的答案。 基本上,我想将对象传递到一个静态方法,并且该方法将只返回基于所述对象的值/属性的输出。 对于每一个电话,我创建的对象的新实例,并没有以任何方式,我将修改方法里面的对象没有机会。 现在,我的问题是,将JVM创建静态方法和局部变量压入堆栈(不包括因为它会在堆中的对象)由多个线程每次调用一个新的实例? 对于什么,我想实现一个明确的说法,这里是我的代码:

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:

因为我没有把一个synchronized关键字,输出每次都会有所不同,它看起来类似以下内容:(输出是正确的,这也正是我期待,我只是想澄清,我在正确的道路上因为我不希望使用同步,因为它会减慢的过程,因为每个线程必须等待另一个线程来完成,然后才能调用静态方法)

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

Answer 1:

JVM会创建多个线程每次调用静态方法和局部变量压入堆栈(不包括因为它会在堆中的对象)的一个新实例?

是的,这是完全正确的。

如果一个静态方法只是指局部变量,它会自动线程安全的。 (事实上​​,这适用于非静态方法为好。)

一般来说,虽然,我会说你应该避免static如果可能的话。 一般来说它使代码难于测试和推理由于静态成员是在全球感。



Answer 2:

static方法是没有问题的,只有static变量将在线程间共享。

所以两个线程调用

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

不会遇到问题。

static int tmp;

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

将失败的多线程,因为一个线程可能会覆盖anothers tmp值。

局部变量,即使在static方法,仍然是当地的,因此是安全的。

使用static方法还是不错的。 它强调,该方法不需要访问对象变量。 使用static非恒定的变量是容易出错,避免这种不惜一切代价(与使用同步的恒定,如果你需要访问的变量)。



文章来源: Multiple Threads passing an object reference to static helper method