首页 > 代码库 > 使用synchronized(非this对象)同步代码块解决脏读问题

使用synchronized(非this对象)同步代码块解决脏读问题

首先通过示例来学习验证多个线程调用同一个方法时随机的。

package syn_out_asyn;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/1/19 0019.
 */
public class MyList {
    private List list = new ArrayList();
    synchronized public void add(String username){
        System.out.println("ThreadName="+Thread.currentThread().getName()+"执行了add方法");
        list.add(username);
        System.out.println("ThreadName="+Thread.currentThread().getName()+"退出了add方法");
    }
    synchronized public int getSize(){
        System.out.println("ThreadName= "+Thread.currentThread().getName()+"执行了getSize方法");
        int sizeValue=http://www.mamicode.com/ list.size();
        System.out.println("ThreadName= "+Thread.currentThread().getName()+"退出了getSize方法");
        return  sizeValue;
    }
}
package syn_out_asyn;

/**
 * Created by Administrator on 2017/1/19 0019.
 */
public class ThreadA extends Thread {
    private MyList list;
    public ThreadA (MyList list){
        super();
        this.list = list;
    }

    public void run(){
        for(int i=0;i<10000;i++){
            list.add("ThreadA"+(i+1));
        }
    }
}
package syn_out_asyn;

/**
 * Created by Administrator on 2017/1/19 0019.
 */
public class ThreadB extends Thread {
    private MyList list;
    public ThreadB(MyList list){
        super();
        this.list = list;
    }
    public void run(){
        for(int i=0;i<10000;i++){
            list.add("threadB"+(i+1));
        }
    }
}
package syn_out_asyn;

/**
 * Created by Administrator on 2017/1/19 0019.
 */
public class Run {
    public static void  main(String[] args){
        MyList myList = new MyList();
        ThreadA threadA =  new ThreadA(myList);
        threadA.setName("A");
        threadA.start();
        ThreadB threadB = new ThreadB(myList);
        threadB.setName("B");
        threadB.start();
    }
}
执行结果:
ThreadName=A执行了add方法
ThreadName=A退出了add方法
ThreadName=A执行了add方法
ThreadName=A退出了add方法
ThreadName=A执行了add方法
ThreadName=A退出了add方法
ThreadName=B执行了add方法
ThreadName=B退出了add方法
ThreadName=B执行了add方法
ThreadName=B退出了add方法
ThreadName=B执行了add方法
ThreadName=B退出了add方法

从结果来看,同步块中的代码是同步打印的,当前线程的执行和退出时成对出现的。但线程A和线程B的执行却是异步的,这就有可能出现脏读的环境。由于线程执行的方法的顺序不确定,所以当A和B两个线程执行带有分之判断的方法时,就会出现逻辑上的错误,有可能出现脏读。

使用synchronized(非this对象)同步代码块解决脏读问题