[英]What will be effect of using static variable or final static varibale on permormance
[英]What is the effect of final variable declaration in methods?
简单服务器的经典示例:
class ThreadPerTaskSocketServer {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
Runnable task = new Runnable() {
public void run() {
handleRequest(connection);
}
};
new Thread(task).start();
}
}
}
为什么将Socket
声明为final
? 是因为处理请求的新Thread
可以引用该方法中的socket
变量并导致某种ConcurrentModificationException
吗?
在这种情况下,该变量必须是最终变量,才能在匿名Runnable
实现中使用。
这是因为当变量已经超出范围并因此消失时,该对象将存在。 对象获取变量的副本。 为了隐藏此变量,该变量必须为final,以便没有人期望一个副本中的更改对其他副本可见。
考虑以下示例:
class A {
B foo() {
final C c;
return new B() {
void goo() {
// do something with c
}
}
}
}
// somewhere else in the code
A a = new A();
B b = a.foo();
b.goo();
如果c 不是最终值,则到达b.goo()
,它将指向垃圾,因为该c将被垃圾回收-方法调用结束后的局部变量。
您不仅需要将其声明为final。 否则,编译器将无法在匿名Runnable类实现中使用它。
声明一个方法变量final意味着它的值不能改变; 只能设置一次。 在这种情况下如何应用?
我已经知道匿名类的这种限制已有一段时间了,但是我从来不完全明白为什么。 我看到到目前为止,没有人真正做到这一点。 一些谷歌搜索出现在下面,我认为可以很好地解释它。
匿名本地类可以使用本地变量,因为编译器会自动为该类提供一个私有实例字段,以保存该类使用的每个本地变量的副本。 编译器还将隐藏参数添加到每个构造函数中,以初始化这些自动创建的私有字段。 因此,局部类实际上并不访问局部变量,而只是访问它们自己的私有副本。 唯一可以正常工作的方法是将局部变量声明为final,这样可以保证它们不会更改。 有了这种保证,就可以确保局部类的内部副本变量准确地反映了实际的局部变量。
致谢: http : //renaud.waldura.com/doc/java/final-keyword.shtml#vars
当然并不明显,我认为编译器确实应该对开发人员隐藏。
局部变量不在线程之间共享。 (局部变量是激活记录的一部分,每个线程都有自己的激活记录)。
由于connection
是局部变量,因此无法在线程之间共享它。 由于它不是在线程之间共享的,因此需要将其设置为final
,因此它是局部变量(可以将其视为常数)并不重要。
它无意解决ConcurrentModificationException。 在方法嵌套类(例如匿名内部类)中使用的任何局部变量都必须声明为final。 在这里查看上周的类似讨论:
实际上,在使用线程的情况下,这里对线程安全性的贡献很小。 线程之间的最终变量不会有可见性问题。 但是,这根本不能保证线程安全。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.