美文网首页
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