一个线程不安全的类
public class Count {
private int num;
public void count() {
for(int i = 1; i <= 10; i++) {
num += i;
}
System.out.println(Thread.currentThread().getName() + "-" + num);
}
}
正常的理解,调用count()应该会输出55
在主函数中启动10个线程:
public class ThreadTest {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
Count count = new Count();
public void run() {
count.count();
}
};
for(int i = 0; i < 10; i++) {
new Thread(runnable).start();
}
}
}
输出结果如下:
Thread-0-55
Thread-1-110
Thread-2-165
Thread-4-220
Thread-5-275
Thread-6-330
Thread-3-385
Thread-7-440
Thread-8-495
Thread-9-550
只有Thread-0线程输出的结果是我们期望的,其他的跟想象中的不符,为何?
每个线程都有自己的工作内存(线程栈),工作内存存储了主内存count对象的一个副本,当线程操作count对象时,首先从主内存复制count对象到工作内存中,然后执行代码count.count(),改变了num值,最后用工作内存中的count刷新主内存的 count。
可以看出,多个线程对同一个实例类的同一个变量操作是不安全的,不安全体现在这个成员变量可能发生非原子性的操作,然而,变量定义在方法内(局部变量)、多个线程访问同一个对象中的同步方法是安全的
java线程的两个特性:可见性(也就是工作内存会刷新主内存)、有序性(结果取决于线程调度的精准时序)
网友评论