线程正确同步的前提:
1、有多个线程操作共享数据
2、有多条操作共享数据的语句,需要分别对每个线程操作共享语句块加synchronized,即使某个线程操作的语句只有一条,也需要加synchronized。
3、多个线程synchronized加的锁,必须是同一个锁。
简单测试例子
如果同步失败,则会出现姓名和性别对应错误,因为可能在更改姓名后且未更改性别前,pop打印事件。同步成功,则不会发生姓名和性别对应错误。
package com.zyf.test.product;
public class ProductConsumer {
public static void main(String[] args) {
Resource res = new Resource();
PutRes put = new PutRes(res);
PopRes pop = new PopRes(res);
Thread tput = new Thread(put);
Thread tpop = new Thread(pop);
tput.start();
tpop.start();
}
}
class Resource{
String name;
String sex;
}
class ObjTest{
static Object obj = new Object();
}
class PutRes implements Runnable{
private Resource res;
PutRes(Resource res){
this.res = res;
}
@Override
public void run() {
boolean b = true;
while(true){
if(b){
synchronized(ObjTest.obj){
res.name = "张三";
res.sex = "男";
}
b = false;
}else{
synchronized(ObjTest.obj){
res.name="sary__";
res.sex="女!!!!!";
}
b = true;
}
}
}
}
class PopRes implements Runnable{
private Resource res;
PopRes(Resource res){
this.res = res;
}
@Override
public void run() {
while(true){
synchronized(ObjTest.obj){
System.out.println(res.name+"__"+ res.sex);
}
}
}
}
附录:非静态synchronized同步方法,相当于synchronized语句块的this调用
静态synchronized同步方法,相当于synchronized语句块的 类.class 调用