你能在不同的线程上调用相同的方法吗?

时间:2014-10-17 09:13:02

标签: java android multithreading android-studio

我知道真的没有问题,但我试图理解方法和线程如何作为业余程序员工作。我确信这对我来说基本缺乏理解,但希望一些好人可以让我直截了当。

我想知道的是,如果您使用多个线程多次调用相同的方法,您是否创建了每个方法的沙盒版本,这些版本彼此独立地行动或者它们可以相互干扰。例如,我在下面敲了一些非常简单的代码来试图说明我的意思。

因此,在示例中,我们有一个单击按钮时调用的方法。它需要两个数字并将它们输入到第二个方法中,将它们加在一起并返回结果。这似乎是直截了当的。但想象一下,我们想用相同的方法进行另一次计算,但我们并不想等待第一次计算完成。我们可以调用在单独的线程上添加数字的方法,这样它就不会阻止UI线程。凉。好的,但如果我们这样做两次怎么办?还是三次?

我想问的是什么时候" doSum"在传入它的数字下面第一次调用10和20.代码在一个单独的线程上运行该方法并应该返回答案30.第二次调用它时数字是30和50,结果应该是80如果出于某种原因,第一个线程中的计算仍在进行中,当我第二次调用相同的方法时它会被覆盖吗?结果是否有可能被归还为80或140?

这对任何人都有意义吗?

public void onbuttonclicked(View v) {

int number1;
int number2;
int result1, result2, result3;


//first callculation --------------------------------------
number1 = 10;
number2 = 20;
    Thread t1 = new Thread(new Runnable() {
        public void run() {
        result1 = doSum(number1, number2);
            }
    });
    t1.start();


//second callculation -----------------------------------
number1 = 30;
number2 = 50;
    Thread t2 = new Thread(new Runnable() {
        public void run() {
        result2 = doSum(number1, number2);
            }
    });
    t2.start();

//third callculation -----------------------------------------
number1 = 60;
number2 = 80;
    Thread t3 = new Thread(new Runnable() {
        public void run() {
        result3 = doSum(number1, number2);
            }
    });
    t3.start();


}


public static int doSum(int a, int b)
{
    int result = a + b;
    return result;
}

4 个答案:

答案 0 :(得分:5)

你应该知道的主要有两件事。

  1. 如果2个线程调用相同的方法,则每个线程将为该方法使用不同的 Stack Frame 。因此,方法局部变量是线程安全的。在一种方法的局部变量中所做的更改不会干扰其他线程的更改。

  2. 当两个线程都修改了共享资源时,您应该(通常)担心线程安全/干扰。

  3. PS:你的doSum()做了很少的处理。智能JVM实际上可能内联方法。

答案 1 :(得分:0)

在这种情况下,doSum()没有问题。它仅使用传递的参数和本地变量。所以,doSum()有:

1)代码。除非自我修改,否则二进制指令代码是线程安全的(从不这样做!)。

2)本地变量和参数。在大多数体系结构中,这意味着注册和堆栈存储。由于每个线程都有自己的寄存器集和堆栈,因此不存在冲突。

答案 2 :(得分:0)

这些线程独立运行,因此结果应是随机的,所有这些都取决于它们的速度。这是一种典型的竞争条件。也许你应该阅读有关竞争条件的内容,这应该不难理解。

随机意味着你的t1可以在number1 = 30之后的点处调用doSum(),因此result1应为50.这只是一个例子。

答案 3 :(得分:0)

java中的线程独立运行即。取决于你如何配置。当线程进入图片时,结果总是变得不可预测,意味着你第一次尝试的结果,它不会进入第二次。

在你的情况下,onbuttonclicked()将由主线程处理/运行,这将创建其他3个线程。它完全取决于ThreadScheduler,该线程将首先运行。因为这个操作发生得非常快,这意味着初始化过程可能(并不总是)过来。

所以在这里,第一个线程的结果可能是140.它是不可预测的。

希望这对你有所帮助。