美文网首页
synchronized同步代码块

synchronized同步代码块

作者: 迷糊小生 | 来源:发表于2019-03-25 22:22 被阅读0次

�用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待比较长时间,在这样的情况下可以使用synchronized同步代码块来解决。

package other.thread3;

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

/**
 * 只能放一个元素的List
 * @author xml
 *
 */
public class MyOneList {
    private List<String> list = new ArrayList<>();

    public synchronized void add(String data) {
        list.add(data);
    }
    
    public synchronized Integer getSize() {
        return list.size();
    }
}
package other.thread3;

public class MyService {

    public MyOneList addServiceMethod(MyOneList list,String data) {
        try {
            if(list.getSize() < 1) {
                Thread.sleep(2000);
                list.add(data);
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }
    
}
package other.thread3;

public class ThreadA extends Thread {
    private MyOneList list;
    public ThreadA(MyOneList list) {
        this.list = list;
    }
    @Override
    public void run() {
        MyService service = new MyService();
        service.addServiceMethod(list, "AAAA");
    }
}
package other.thread3;

public class ThreadB extends Thread {
    private MyOneList list;
    public ThreadB(MyOneList list) {
        this.list = list;
    }
    @Override
    public void run() {
        MyService service = new MyService();
        service.addServiceMethod(list, "BBBB");
    }
}
package other.thread3;

public class Test {

    public static void main(String[] args) throws InterruptedException {
        MyOneList list = new MyOneList();
        ThreadA threadA = new ThreadA(list);
        threadA.start();
        ThreadB threadB = new ThreadB(list);
        threadB.start();
        Thread.sleep(3000);
        System.out.println("getSize" + list.getSize());
    }

}
image.png

'脏读'出现了,出现的原因是两个线程在addServiceMethod方法中异步的返回list参数的大小,解决的办法就是同步化。

package other.thread3;

public class MyService {

    public MyOneList addServiceMethod(MyOneList list,String data) {
        try {
            synchronized (list) {
                if(list.getSize() < 1) {
                    Thread.sleep(2000);
                    list.add(data);
                }
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }
    
}

由于list参数对象在项目中是一份实例,是单例的,而且也正需要对list参数的getSize()方法做同步的调用,所以就对list参数进行同步处理。

相关文章

网友评论

      本文标题:synchronized同步代码块

      本文链接:https://www.haomeiwen.com/subject/xtvmvqtx.html