5、共享模型之不可变

本文探讨了不可变类的设计原理,如何通过final关键字保证其只读性,并提到了保护性拷贝策略。同时,讲解了无状态类的线程安全性以及享元模式在重用对象时的应用,以连接池为例,展示了如何结合这些概念实现高效并发控制。
摘要由CSDN通过智能技术生成

该栏目讲叙多线程基础、共享模型的内存、管程、无锁、不可变设计和多线程并发工具


不可变类的设计

  • 设计原则
    • final 的使用
      • 属性用 final 修饰保证了该属性是只读的,不能修改
      • 类用 final 修饰保证了该类中的方法不能被覆盖,防止子类无意间破坏不可变性
    • 保护性拷贝:通过创建副本对象来避免共享问题(Arrays.copyOf())
  • 缺点:由于保护性拷贝会产生大量副本,这样会增加内存的负担,可以关联享元模式思想设计

无状态类的设计

  • :在设置类的时候不设置成员变量,这种没有任何成员变量的类是线程安全的,也是无状态的

享元模式

  • 场景:需要重用数量有限的同一类对象时
  • 连接池案例
/**
 * 连接实体(不可变类)
 */
@Data
public final class Connection {

    private final String name;

    public Connection(String name) {
        this.name = name;
    }

}

/

/**
 * 连接池
 */
public class ConnectionPool {

    private final int capacity;

    private final Connection[] connections;

    private final AtomicIntegerArray status;

    public ConnectionPool(int capacity) {
        this.capacity = capacity;
        this.connections = new Connection[capacity];
        this.status = new AtomicIntegerArray(capacity);
        for (int i = 0; i < capacity; i++) {
            this.connections[i] = new Connection("连接" + i);
        }
    }

    /**
     * 获取连接对象
     *
     * @return 连接对象
     */
    public Connection borrow() {
        while (true) {
            for (int i = 0; i < capacity; i++) {
                if (status.get(i) == 0) {
                    if (status.compareAndSet(i, 0, 1)) {
                        return connections[i];
                    }
                }
            }
            synchronized (this) {
                try {
                    System.out.println("wait...");
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 归还连接对象
     *
     * @param conn 连接对象
     */
    public void free(Connection conn) {
        for (int i = 0; i < capacity; i++) {
            if (connections[i] == conn) {
                status.set(i, 0);
                synchronized (this) {
                    System.out.println("notify...");
                    this.notifyAll();
                }
            }
        }
    }

}

/

/**
 * 测试类
 */
public class PoolDemo {

    public static void main(String[] args) {
        ConnectionPool pool = new ConnectionPool(2);
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    final Connection conn = pool.borrow();
                    System.out.println("获取的连接对象:" + conn);
                    TimeUnit.SECONDS.sleep(2);
                    pool.free(conn);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值