对Java中的静态修饰符还是不太了解.如果定义个静态方法,方法内部不涉及调用外部变量,比如说这个方法是为了解决某个问题的一个工具方法,就像"Array.getLong(arg0, arg1)"这种一样,那么这个静态方法在遇到多线程问题的时候是否会存在安全隐患呢? 我写了下面一段代码,用两个线程不停的去调用类中的一个静态方法,试问:Sytem.err.println()中的内容是否会打印出来?
我执行了很长时间也没见打印出来,对于概念也模糊不清,所以依然无法做出判断,求帮忙解决下我的疑惑。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public
class
Test
implements
Runnable {
public
static
void
main(String[] args) {
new
Thread(
new
Test(),
"Thread 1"
).start();
new
Thread(
new
Test(),
"Thread 2"
).start();
}
public
static
void
show() {
int
a =
0
;
if
(a !=
0
)
System.err.println(
"未处理前:"
+ a);
a++;
}
@Override
public
void
run() {
while
(
true
) {
show();
}
}
}
|
Java中静态方法是否属于线程安全
首先要搞清楚变量的作用域和线程安全的数据是针对哪个作用域的变量而言。
1:上面的代码,说的是方法内的局部变量。每个线程在启动以后,都有自己的栈区,这个内存区域会保存对应线程在运行期间进行方法调用的方法变量和方法内的局部变量。所以从这份分析来看,方法内部变量始终只存在于他所在的线程,也就不会有线程安全方面的问题。当然,如果是引用类型的对象,由于对象本身不在每个线程的栈区,而是在java堆中,所以就要考虑临界资源的多线程访问问题。
2:线程安全是针对多个线程能在运行期间共同访问到的临界资源的访问而言的。如第一点所说,这样的临界资源是指在线程自己的栈区外的资源,比如类实例的成员变量,类实例本身。。
- fdhay计算机中,操作数和操作指令是不同的概念。临界资源只针对操作数才有意义。而操作指令只是 计算机线程的执行序列,哪个线程都可以执行,都可以同时执行,这个跟 线程安全(只针对操作数才有意义)毫无关系。我已经说到,方法内的局部变量,已经是放在每个线程自己的栈区,这个局部变量作为操作数,就只能被他自己的线程访问到。(2年前)
- 姓骚扰现在。静态方法和静态成员变量一样,都是属于类和实例共享的,这会搞不清楚的就是静态方法中定义的变量到底是属于类共享级的还是非共享的?
线程安全和static没啥关系。