代码示例:
package com.test;
/*
* x,y值为什么不能保持相同;
*
*/
public class Pair implements Runnable{
boolean b = false;
private int x;
private int y;
public Pair(int x,int y){
this.x = x;
this.y = y;
}
public Pair(){
}
public void incrementX(){
x++;
}
public void incrementY(){
y++;
}
public String toString(){
return "x: " + x + " ,y: "+y;
}
public void run(){
while(!b){
synchronized(this){
incrementX();
incrementY();
}
}
}
public boolean checkState(){
if(x!=y){
System.out.println("values not equal:"+this);
return b = true;
}
return b;
}
public static void main(String args[]){
Pair p = new Pair(0,0);
new Thread(p).start();
while(true){
System.out.println(p);
if(p.checkState()){
System.exit(0);
}
}
}
}
为什么以上代码是线程不安全的?
在百科里面有这么一句:当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的除synchronized(this)同步代码块以外的部分。
分析:请注意,在主线程中,会在某一个时刻调用p.checkState(),而这个方法并没有和run方法中的
synchronized块代码同步。因为checkState方法不是同步方法。某一个时刻,synchronized块失去了cpu。
而下一个却要执行主线程的p.checkState(),这个时候是可以访问x 和 y变量的。
解决的方法是,需要同步的方法上,加一个synchronized。这样就能和run方法中的synchronized块进行同步。