多个线程对同一个对象的变量进行并发访问,产生的结果就是“脏读”。
对局部变量的访问
package com.example.test;
public class Test168 {
public static void main(String[] args) {
Test168 t = new Test168();
Thread tt = new Thread(new MyThreadA(t));
Thread tt1 = new Thread(new MyThreadB(t));
tt.start();
tt1.start();
}
public void show(String name) {
int num = 0;
if(name.equals("a")) {
num = 100;
System.out.println("a set over");
}
if(name.equals("b")) {
num = 200;
System.out.println("b set over");
}
System.out.println(name+" "+num);
}
}
class MyThreadA implements Runnable{
private Test168 t;
public MyThreadA(Test168 t) {
super();
this.t = t;
}
@Override
public void run() {
// TODO Auto-generated method stub
t.show("a");
}
}
class MyThreadB implements Runnable{
private Test168 t;
public MyThreadB(Test168 t) {
super();
this.t = t;
}
@Override
public void run() {
// TODO Auto-generated method stub
t.show("b");
}
}
如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝,一个线程对该局部变量的改变不会影响到其他线程。每个线程执行时将会把局部变量放在各自栈帧的工作内存中,故线程是安全的。
对成员变量访问
将上述的代码做如下修改:在Test168中定义
int num = 0;
你会发现出现线程不安全。多个线程对象之间共享了该变量。
对静态变量的访问
将上述的代码做如下修改:在Test168中定义
static int num = 0;
你会发现线程出现不安全,静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。
对于多个对象的变量访问
上述的代码,都是针对的是同一个对象,下面看看多个对象。
上述针对单个对象满足多线程访问线程安全,那多个对象肯定没问题,那么我们就看不满足的。
多个对象多线程访问成员变量
package com.example.test;
public class Test168 {
public static void main(String[] args) {
Thread tt = new Thread(new MyThreadA());
Thread tt1 = new Thread(new MyThreadB());
tt.start();
tt1.start();
}
public void show(String name) {
int num = 0;
if(name.equals("a")) {
num = 100;
System.out.println("a set over");
}
if(name.equals("b")) {
num = 200;
System.out.println("b set over");
}
System.out.println(name+" "+num);
}
}
class MyThreadA implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
Test168 t= new Test168();
t.show("a");
}
}
class MyThreadB implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
Test168 t= new Test168();
t.show("b");
}
}
如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变量的修改将互不影响,故线程安全。
多对象多线程对静态变量访问
将上述的代码做如下修改:在Test168中定义
static int num = 0;
你会发现,静态变量即类变量,位于方法区,为所有对象共享,虽然,你创建不同的Test168对象,但是是不是都是Test168对象,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。
参看http://blog.csdn.net/aaa1117a8w5s6d/article/details/8295527