Android开发 - synchronized 关键字控制多个线程对共享资源的访问解析

什么是 synchronized

  • synchronized 一个关键字,用于实现线程同步。其主要作用控制多个线程共享资源访问,确保被 synchronized 修饰的代码块或方法同一时间只有一个线程可以执行,从而避免数据不一致的问题

为什么需要 synchronized

  • 多线程编程中,多个线程可能同时访问修改共享数据。如果不加以控制,可能会导致数据不一致程序错误例如:一个线程正在写入一个变量,另一个线程正在读取该变量,在这种情况下,可能会读取到不完整错误的数据。为了解决这个问题,使用 synchronized确保某个代码块或方法在同一时间只被一个线程执行

synchronized 的用法

修饰实例方法

  • synchronized 用来修饰一个实例方法时,它会对当前对象实例 (this) 加锁。也就是说,同一个对象所有 synchronized 实例方法同一时间只能一个线程访问

    public class Counter {
        private int count = 0;
    
        // synchronized 修饰符用于同步方法
        // increment() 方法被 synchronized 修饰,这意味着如果有多个线程尝试同时调用 increment() 方法,只有一个线程可以进入,其他线程必须等待,直到当前线程执行完毕
        public synchronized void increment() {
            count++;
        }
    
        public int getCount() {
            return count;
        }
    }
    

修饰静态方法

  • synchronized 用来修饰一个静态方法时,它会对当前类Class 对象加锁。这意味着同一个类所有 synchronized 静态方法同一时间只能一个线程访问

    public class Counter {
        private static int count = 0;
    
        // synchronized 修饰符用于同步静态方法
        // increment() 方法是静态方法,被 synchronized 修饰后,所有线程在同一时间只能有一个线程可以执行这个方法
        public static synchronized void increment() {
            count++;
        }
    
        public static int getCount() {
            return count;
        }
    }
    

修饰代码块

  • synchronized 还可以用来修饰代码块,这样可以锁定一个特定的对象,而不是整个方法。这种用法可以提供更细粒度控制,可以提高性能

    public class Counter {
        private int count = 0;
        private final Object lock = new Object();
    
        public void increment() {
            // increment() 方法中的代码块被 synchronized 锁定,锁定对象是 lock。只有一个线程可以进入 synchronized (lock) 内部的代码块,其他线程需要等待
            synchronized (lock) {
                count++;
            }
        }
    
        public int getCount() {
            return count;
        }
    }
    

总结

  • synchronized 是一种同步机制,用于防止多个线程同时访问共享资源

  • 可以使用 synchronized 修饰方法或代码块,以确保线程安全

  • 使用 synchronized 可以防止数据不一致问题,但也可能引起线程阻塞,从而影响性能。因此,在使用时尽量锁定尽可能少的代码块确保程序效率

posted @ 2024-08-27 16:23  阿俊学JAVA  阅读(10)  评论(0编辑  收藏  举报