1_基础知识_chapter04_对象的组合_4_在现有的线程安全类中添加功能

本文探讨了在不破坏线程安全性前提下,通过直接修改类、扩展类、客户端加锁和组合四种方法,为现有类添加自定义功能的策略。每种方法均有其优劣,需根据具体场景选择。
  • 很多情况下应该重用现有的类, 添加自定义的功能, 此时需要在不破坏线程安全性的情况下添加新的操作

    (1) 方法一: 直接修改原始的类

    优点: 同步策略仍然处于同一个源代码文件中, 更容易理解和维护

    缺点: 常常无法修改源代码

    (2) 方法二: 扩展这个类

    同步策略分布到了各个文件中, 并且要确定的得知基类的同步策略

示例

    @ThreadSafe
    public class BetterVector<E> extends Vector<E> {

        // When extending a serializable class, you should redefine serialVersionUID
        static final long serialVersionUID = -3963416950630760754L;

        public synchronized boolean putIfAbsent(E x) {

            boolean absent = !super.contains(x);
            if (absent) {
                super.add(x);
            }

            return absent;
        }
    }

(3) __方法三: 客户端加锁机制__

扩展类的功能, 但不是扩展类本身, 而是将扩展代码放入__辅助类__中

__客户端加锁__: 对于使用某个对象X的客户端代码, 使用__X本身用于保护其状态的锁__来保护这段客户代码

__所以, 使用客户端加锁方式, 必须从源码中找到X使用的是哪一个锁__


示例

错误示例

    @NotThreadSafe
    class BadListHelper<E> {

        public List<E> list = Collections.synchronizedList(new ArrayList<E>());

        public synchronized boolean putIfAbsent(E x) {

            boolean absent = !list.contains(x);

            if (absent) {
                list.add(x);
            }

            return absent;
        }
    }

正确示例

    @ThreadSafe
    class GoodListHelper<E> {

        public List<E> list = Collections.synchronizedList(new ArrayList<E>());

        public boolean putIfAbsent(E x) {

            synchronized (list) {
        
                boolean absent = !list.contains(x);

                if (absent) {
                    list.add(x);
                }

                return absent;
            }
        }
    }

正确示例和错误示例的区别在于使用锁的不同, 深入Collections.synchronizedList的源码, 会发现它使用的锁就是Collections.synchronizedList对象本身, 所以辅助类中也要使用Collections.synchronizedList本身作为锁


和方法二一样, 客户端加锁方式也存在同步策略分布在各个类中的问题, 这样当底层源码的同步策略改变时可能会不稳。

(4) __方法四: 组合__

__使用Java监视器模式, 对内部的对象完全由类本身提供的锁保护, 不管底层的类是否线程安全__

示例

    @ThreadSafe
    public class ImprovedList<T> implements List<T> {

        private final List<T> list;

        public ImprovedList(List<T> list) {
            this.list = list;
        }

        public synchronized boolean putIfAbsent(T x) {

            boolean contains = list.contains(x);
            if (contains) {
                list.add(x);
            }

            return !contains;
        }

        // Plain vanilla delegation for List methods.
        // Mutative methods must be synchronized to ensure atomicity of putIfAbsent.

        public synchronized boolean addAll(Collection<? extends T> c) {
            return list.addAll(c);
        }

        public synchronized boolean addAll(int index, Collection<? extends T> c) {
            return list.addAll(index, c);
        }

        public synchronized boolean removeAll(Collection<?> c) {
            return list.removeAll(c);
        }

        public synchronized boolean retainAll(Collection<?> c) {
            return list.retainAll(c);
        }

        public synchronized void clear() {
            list.clear();
        }

        public synchronized boolean add(T e) {
            return list.add(e);
        }

        public synchronized boolean remove(Object o) {
            return list.remove(o);
        }


        public int size() {
            return list.size();
        }

        public boolean isEmpty() {
            return list.isEmpty();
        }

        public boolean contains(Object o) {
            return list.contains(o);
        }

        public Iterator<T> iterator() {
            return list.iterator();
        }

        public Object[] toArray() {
            return list.toArray();
        }

        public <T> T[] toArray(T[] a) {
            return list.toArray(a);
        }

        public boolean containsAll(Collection<?> c) {
            return list.containsAll(c);
        }

        public boolean equals(Object o) {
            return list.equals(o);
        }

        public int hashCode() {
            return list.hashCode();
        }

        public T get(int index) {
            return list.get(index);
        }

        public T set(int index, T element) {
            return list.set(index, element);
        }

        public void add(int index, T element) {
            list.add(index, element);
        }

        public T remove(int index) {
            return list.remove(index);
        }

        public int indexOf(Object o) {
            return list.indexOf(o);
        }

        public int lastIndexOf(Object o) {
            return list.lastIndexOf(o);
        }

        public ListIterator<T> listIterator() {
            return list.listIterator();
        }

        public ListIterator<T> listIterator(int index) {
            return list.listIterator(index);
        }

        public List<T> subList(int fromIndex, int toIndex) {
            return list.subList(fromIndex, toIndex);
        }
    }

所有需要同步的方法都使用ImprovedList本身的锁, 而不必在意封装对象的同步策略
  • 同步策略应该文档化

    定义好

    (1) 哪些变量为volatile

    (2) 哪些变量用锁保护

    (3) 哪些变量必须不可变或者线程封闭

    (4) 哪些操作必须是原子操作

    等……

内容概要:本文详细介绍了一种基于Simulink的表贴式永磁同步电机(SPMSM)有限控制集模型预测电流控制(FCS-MPCC)仿真系统。通过构建PMSM数学模型、坐标变换、MPC控制器、SVPWM调制等模块,实现了对电机定子电流的高精度跟踪控制,具备快速动态响应和低稳态误差的特点。文中提供了完整的仿真建模步骤、关键参数设置、核心MATLAB函数代码及仿真结果分析,涵盖转速、电流、转矩和三相电流波形,验证了MPC控制策略在动态性能、稳态精度和抗负载扰动方面的优越性,并提出了参数自整定、加权代价函数、模型预测转矩控制和弱磁扩速等优化方向。; 适合人群:自动化、电气工程及其相关专业本科生、研究生,以及从事电机控制算法研究与仿真的工程技术人员;具备一定的电机原理、自动控制理论和Simulink仿真基础者更佳; 使用场景及目标:①用于永磁同步电机模型预测控制的教学演示、课程设计或毕业设计项目;②作为电机先进控制算法(如MPC、MPTC)的仿真验证平台;③支撑科研中对控制性能优化(如动态响应、抗干扰能力)的研究需求; 阅读建议:建议读者结合Simulink环境动手搭建模型,深入理解各模块间的信号流向与控制逻辑,重点掌握预测模型构建、代价函数设计与开关状态选择机制,并可通过修改电机参数或控制策略进行拓展实验,以增强实践与创新能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值