gpt4 book ai didi

multithreading - 可以从Scala的子线程中更改局部变量

转载 作者:行者123 更新时间:2023-12-03 13:16:36 24 4
gpt4 key购买 nike

今天,我试图了解JVM中的内存管理,并且遇到了以下问题:是否可以从同一函数中产生的两个线程中更改局部变量?
在Java中,如果尝试执行类似的操作,则代码将无法编译,并显示错误消息:“从内部类引用的局部变量必须是最终的或有效地是最终的”

public class MyClass {
static void f() throws Exception {
int x = 0;

Thread t1 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 1000; i++) {
x = x + 1;
}
}
});

Thread t2 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i < 1000; i++) {
x = x - 1;
}
}
});

t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
public static void main(String args[]) throws Exception {
for(int i = 0; i < 20; i++) {
f();
}
}
}
但是,Scala中的等效代码确实可以毫无问题地进行编译和运行(尽管可能存在竞争条件):
def f(): Unit = {
var x = 0

val t1 = new Thread(new Runnable {
override def run(): Unit =
(1 to 1000).foreach(_ => {x = x + 1})
})

t1.start()
val t2 = new Thread(new Runnable {
override def run(): Unit =
(1 to 1000).foreach(_ => {x = x - 1})
})
t2.start()
t1.join()
t2.join()
println(x)
}

(1 to 20).foreach(_ => f())
为什么每种情况下的行为都不同?

最佳答案

在Scala中,lambda和扩展类都是匿名类,可以捕获局部变量。 scala.runtime软件包为此目的包含一些额外的类。它们有效地将局部变量提升为可以共享其实例的另一个类的实例变量:https://github.com/scala/scala/blob/v2.13.3/src/library/scala/runtime/ObjectRef.java

关于multithreading - 可以从Scala的子线程中更改局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62816908/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com