您的位置:首页 > 编程语言 > Java开发

Java Synchronized用法1

2013-09-28 23:09 323 查看
1.背景

Java中需要资源共享,如对象中的一些数据,而数据是私有的,往往通过创建方法去访问这些数据,当多个线程去访问这些数据(调用方法)时,往往会产生冲突,Synchronized可以有效的防止冲突(Thinking in java14.2.2)。

2.原理

使用Synchronized去修饰方法时,调用此方法的对象将会被“上锁”,此时锁住的是对象,不是代码块或者此方法。

eg.

一个对象包含两个synchronized方法funcA() and funB(),线程1去访问A,对象此时被上锁,线程2、3....无法访问funcA() and funcB().

也就是说一个含有Synchronized方法的对象,在任何时间,只允许一个线程访问此对象的Synchronized方法。

3.实例

1000个线程同时对一个对象中的数据进行增减操作。没有使用synchronized之前,输出结果不确定,也就是同一时刻出现至少两个线程访问数据;使用Synchronized之后,输出确定。

public class SyncTest{

int count = 0;
static int number = 1000;

public SyncTest(){

}

public void inc(){
this.count +=1000;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void dec(){
this.count -= 1000;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){

final SyncTest st = new SyncTest();
Thread[] threadArray = new Thread[number];
for(int i=0;i<number;i++){
threadArray[i] = new demoThread(String.valueOf(i),st);
}
for(int i=0;i<number;i++){
threadArray[i].start();
}
for(int i=0;i<number;i++){
try {
threadArray[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(String.valueOf(st.count));
}

}
class demoThread extends Thread{

String name;
SyncTest st;

public demoThread(String name,SyncTest st){
this.name = name;
this.st = st;
}

@Override
public void run() {
// TODO Auto-generated method stub
st.inc();
st.dec();
System.out.println("Thread"+name+" start run");
}

}

4.疑问

当只使用inc方法时,数据时一致的,为何?

解答:若将inc函数中休眠与count自加调换位置,如下,就会发现结果不一致。在上诉例子中因为当线程1访问inc方法时,首先就是执行count自加,此时其他线程获取的是自加之后的count值,不存在冲突。而交换之后,线程1访问inc方法,首先sleep 100ms, 这段时间就可能会被其余的线程抢占而去执行count自加,当返回线程1时,而count值仍然是未加之前的,导致数据异常。

public void inc(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
count += 100;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: