美文网首页面试
Synchronized总结

Synchronized总结

作者: 落魄的安卓开发 | 来源:发表于2017-11-20 16:23 被阅读4次

    java中多线程中的同步机制会对资源进行加锁,保证在同一时间只有一个线程可以操作资源,避免多线程同时访问相同资源发生冲突。

    Synchronized是java中的关键字,它是一种同步锁,可以实现同步机制

    Synchronized修饰对象主要有以下三种:

    1. 修饰普通方法

      • 一个对象中的加锁方法只允许一个线程访问。但要注意‘这种情况下锁的是访问该方法的实例对象,如果多个线程不同对象访问该方法,则无法保证同步
    2. 修饰静态方法

      • 由于静态方法是类方法,所以这个方法锁的是包含这个方法的类,也就是类对象;这样如果多个线程不同的对象访问该静态方法,也是可以保证同步的。
    3. 修饰代码块

      • 修饰普通代码块和修饰普通方法一样;
      • Synchronized静态代码块它的同步效果和修饰方法类似
      • 其中Synchronized(obj)这里的obj可以为类的一个属性、也可以是当前的对象。

    Synchronized修饰方法和代码块的区别:

    Synchronized方法控制范围较大,它会同步对象中所有的Synchronized方法的代码。

    Synchronized代码块控制范围较小,它只会同步代码块中的代码,而位于代码块之外的代码是可以被多个线程访问的。

    简单来说 就是Synchronized代码块更加灵活精确。

    测试代码如下:

    private SynchronizedTest synchronizedTest;
    
    private void testSynchrnoized() {
        synchronizedTest = new SynchronizedTest();
        //测试synchronized修饰普通方法
        //testCommon();
        //测试synchronized修饰静态方法
        //testStatic();
        //测试synchronized修饰代码块
        testArea();
    }
    
    private void testArea() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedTest.setAge2(0);
            }
        }).start();
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                SynchronizedTest test = new SynchronizedTest();
                test.setAge2(1);
            }
        }).start();
    }
    
    private void testStatic() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedTest.setAge1(0);
            }
        }).start();
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                SynchronizedTest test = new SynchronizedTest();
                test.setAge1(1);
            }
        }).start();
    }
    
    private void testCommon() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedTest.setAge(0);
            }
        }).start();
    
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizedTest.setAge(1);
            }
        }).start();
    }
    

    SynchronizedTest类代码如下:

    public class SynchronizedTest {
    
        public int age;
    
        public int getAge() {
            return age;
        }
    
        /**
         * 修饰普通方法:一个对象中的加锁方法只允许一个线程访问。但要注意‘这种情况下锁的是访问该方法的实例对象,如果多个线程不同对象访问该方法,则无法保证同步’
         *
         * @param age
         */
        public synchronized void setAge(int age) {
            if (age == 0) {
                Log.e("result", "Thread0进来访问了");
            } else {
                Log.e("result", "Thread1进来访问了");
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 修饰静态方法: 由于静态方法是类方法,所以这个方法锁的是包含这个方法的类,也就是类对象;这样如果多个线程不同的对象访问该静态方法,也是可以保证同步的。
         *
         * @param age
         */
        public synchronized static void setAge1(int age) {
            if (age == 0) {
                Log.e("result", "Thread0进来访问了");
            } else {
                Log.e("result", "Thread1进来访问了");
            }
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        static SynchronizedTest instance;
        public static  SynchronizedTest getInstance(){
            if(instance == null){
                synchronized (SynchronizedTest.class){
                    instance = new SynchronizedTest();
                }
            }
            return instance;
        }
    
        /**
         * 修饰代码块:
         *          1. 修饰普通代码块和修饰普通方法一样;
         *          2. Synchronized静态代码块它的同步效果和修饰方法类似
         *          3. 其中Synchronized(obj)这里的obj可以为类的一个属性、也可以是当前的对象。
         * @param age
         */
        public static void setAge2(int age) {
            synchronized (SynchronizedTest.class) {
                if (age == 0) {
                    Log.e("result", "Thread0进来访问了");
                } else {
                    Log.e("result", "Thread1进来访问了");
                }
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    相关文章

      网友评论

        本文标题:Synchronized总结

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