Android 同步锁为什么锁不住问题

作者: 翻身不做咸鱼 | 来源:发表于2017-08-13 16:14 被阅读1480次

    Android 同步锁 synchronized,归根到底还是java同步锁问题。下边看一个例子:

    public class Syn {
        public synchronized void start(){
            System.out.println("吃饭...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("睡觉...打豆豆");
        }
    }
    
    public class TestSyn {
    
       static class TestThread extends Thread{
           public TestThread() {
           }
    
           @Override
            public void run() {
                Syn syn = new Syn();
                syn.start();
            }
        }
    
        public static void main(String[] args){
            for (int i = 0; i <4; i++) {
                TestThread t =  new TestThread();
                t.start();
            }
        }
    
    }
    

    吃饭、睡觉、打豆豆这是一个流程。多线程操作,加上同步锁synchronized ,我们看一下结果:

    同步1.png

    我们就纳闷了,为什么线程不是吃饭、睡觉、打豆豆这样一个流程走完。
    Synchronized 不是同步代码块吗?我们试着调整一下代码:

    public class Syn {
        public  void start(){
            synchronized(this){
                System.out.println("吃饭...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("睡觉...打豆豆");
            }
        }
    
    }
    

    结果:


    同步2.png

    很明显, synchronized(this) 同步代码块和 synchronized 同步方法的效果是一样的。那么怎么才能使每个线程都是执行完吃饭、睡觉、打豆豆这样一个流程再执行下一个线程。很明显因为4个线程,new 了四个对象。synchronized(this) 同步代码块和 synchronized 同步方法 针对的是synchronized括号里边的,即this对象。所以:

    package com.lqg.asynchronized;
    
    /**
     * Created by Administrator on 2017/8/13.
     */
    
    public class TestSyn {
    
    
        static class TestThread extends Thread{
            private  Syn mSyn;
            public TestThread(Syn syn) {
                mSyn = syn;
            }
    
            @Override
            public void run() {
                mSyn.start();
            }
        }
    
        public static void main(String[] args){
            Syn syn = new Syn();
            for (int i = 0; i <4; i++) {
                TestThread t =  new TestThread(syn);
                t.start();
            }
        }
    
    }
    
    

    只创建同一个对象,结果:

    同步3.png

    看出来线程同步起到作用了。但是如果是多个对象创建,线程同步又得怎么处理呢?

    public class Syn {
        public static synchronized void start(){
            System.out.println("吃饭...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("睡觉...打豆豆");
        }
    
    }
    
    public class TestSyn {
    
       static class TestThread extends Thread{
           public TestThread() {
           }
    
           @Override
            public void run() {
                Syn syn = new Syn();
                syn.start();
            }
        }
    
        public static void main(String[] args){
            for (int i = 0; i <4; i++) {
                TestThread t =  new TestThread();
                t.start();
            }
        }
    
    }
    
    同步四.png

    和一开始的区别只在于public static synchronized void start() 只加个静态方法,可见同步静态方法相当于同步Syn 这个类。也可以这样写:

        public static  void start(){
            synchronized(Syn.class){
               ......
            }
    
        }
    

    总结:
    1、非静态方法的同步锁只对同一个对象有效。对不同对象起不到同步的作用。
    2、静态方法同步锁锁的是类,锁是整个类对象的锁,这个对象是就是这个类(XXX.class)。
    3、关于锁的范围,能锁住代码块的范围就就尽量不要锁方法。比较加锁之后,要等待其他线程执行完,相对比较耗时。

    相关文章

      网友评论

        本文标题:Android 同步锁为什么锁不住问题

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