线程会共享进程范围内的资源,例如内存句柄和文件句柄,但每个线程都有各自的程序计数器、栈及局部变量等。线程还提供了一种直观的分解模式来充分利用多处理器系统中的硬件并行性,而在同一个程序中的多个线程还可以被同时调度到多个CPU上运行。线程也被称为轻量级进程。在大多数现代操作系统中,都是以线程为基本的调度单位,而不是进程。同一个进程中的所有线程都将共享进程的内存地址空间,因此这些线程都能访问相同的成员变量并在同一个堆上分配对象。
成员变量:
package deep;
public class MemberVariableThread implements Runnable {
private int i;// 成员变量被初始化为0
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() + ":" + i++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (50 == i) {
break;
}
}
}
}
package deep;
public class Test {
public static void main(String[] args) {
MemberVariableThread memberVariableThread = new MemberVariableThread();
Thread thread1 = new Thread(memberVariableThread);
Thread thread2 = new Thread(memberVariableThread);
thread1.start();
thread2.start();
}
}
运行结果:
Thread-0:0
Thread-1:0
Thread-0:1
Thread-1:2
Thread-0:3
Thread-1:4
Thread-0:5
Thread-1:5
Thread-1:6
Thread-0:6
Thread-0:7
Thread-1:8
Thread-0:9
Thread-1:10
Thread-0:11
Thread-1:12
Thread-0:13
Thread-1:14
Thread-0:15
Thread-1:16
Thread-0:17
Thread-1:18
Thread-0:19
Thread-1:20
Thread-0:21
Thread-1:22
Thread-0:23
Thread-1:24
Thread-0:25
Thread-1:26
Thread-0:27
Thread-1:28
Thread-0:29
Thread-1:30
Thread-0:31
Thread-1:32
Thread-0:33
Thread-1:34
Thread-0:35
Thread-1:36
Thread-0:37
Thread-1:38
Thread-0:39
Thread-1:40
Thread-0:41
Thread-1:42
Thread-0:43
Thread-1:44
Thread-0:45
Thread-1:46
Thread-0:47
Thread-1:48
Thread-0:49
在此例中,i是成员变量,两个线程都由同一个类构造,所以共享了同一个i,同时也可以观察到此类不是线程安全的,因为i++不是一个原子性操作。此例仅是为了说明成员变量会被多个线程共享,所以必须采取其他的机制保证线程安全性。
局部变量:
package deep;
public class LocalVariableThread implements Runnable {
@Override
public void run() {
int i = 0; // 每一个线程都会拥有自己的一份局部变量的拷贝,线程之间互不影响,所以会打印100个数字,0到49每个数字都是两遍
while (true) {
System.out.println(Thread.currentThread().getName() + ":" + i++);
if (50 == i) {
break;
}
}
}
}
package deep;
public class Test {
public static void main(String[] args) {
LocalVariableThread localVariableThread = new LocalVariableThread();
Thread thread1 = new Thread(localVariableThread);
Thread thread2 = new Thread(localVariableThread);
thread1.start();
thread2.start();
}
}
运行结果:
Thread-0:0
Thread-1:0
Thread-0:1
Thread-1:1
Thread-0:2
Thread-1:2
Thread-0:3
Thread-1:3
Thread-0:4
Thread-1:4
Thread-0:5
Thread-1:5
Thread-0:6
Thread-1:6
Thread-0:7
Thread-1:7
Thread-0:8
Thread-0:9
Thread-1:8
Thread-0:10
Thread-1:9
Thread-0:11
Thread-1:10
Thread-1:11
Thread-1:12
Thread-1:13
Thread-0:12
Thread-1:14
Thread-0:13
Thread-1:15
Thread-0:14
Thread-1:16
Thread-0:15
Thread-1:17
Thread-0:16
Thread-1:18
Thread-0:17
Thread-1:19
Thread-0:18
Thread-1:20
Thread-0:19
Thread-1:21
Thread-0:20
Thread-1:22
Thread-1:23
Thread-1:24
Thread-1:25
Thread-1:26
Thread-1:27
Thread-1:28
Thread-1:29
Thread-1:30
Thread-1:31
Thread-1:32
Thread-1:33
Thread-0:21
Thread-1:34
Thread-1:35
Thread-0:22
Thread-1:36
Thread-0:23
Thread-0:24
Thread-1:37
Thread-0:25
Thread-1:38
Thread-0:26
Thread-1:39
Thread-0:27
Thread-1:40
Thread-0:28
Thread-1:41
Thread-0:29
Thread-1:42
Thread-0:30
Thread-1:43
Thread-0:31
Thread-1:44
Thread-0:32
Thread-1:45
Thread-0:33
Thread-1:46
Thread-0:34
Thread-1:47
Thread-0:35
Thread-1:48
Thread-0:36
Thread-1:49
Thread-0:37
Thread-0:38
Thread-0:39
Thread-0:40
Thread-0:41
Thread-0:42
Thread-0:43
Thread-0:44
Thread-0:45
Thread-0:46
Thread-0:47
Thread-0:48
Thread-0:49
如注释中所述,由于局部变量对于每一个线程来说都有自己的拷贝,所以各个线程之间不再共享同一个变量,输出结果为100个数字,实际上是两组,每组都是0到49的50个数字,并且两组数字之间随意地穿插在一起。
总结:
原文地址:http://blog.csdn.net/u012552052/article/details/46044045