模式设计II

两阶段终止:

在一个线程中如何优雅的终止另一个线程,让这个线程自己乖乖释放资源,然后终止;

  • stop()方法,资源不要了,直接灭了线程;

  • System.exit(int)方法,进程我都不要了;

  • 使用interrupt和catch的配合使用:

    1. 没有休眠,interrupted会被置true;

    2. 有休眠状态,自动设置打断标志;

      或者直接使用volatile变量作为标记位,并配合interrupt使用;

同步模式之保护性暂停【Guarded Suspension】:

  • 线程之间的协同工作,单个结果之间的传递;

  • 应用:join和Future的实现;

    synchronized(lock){
        while(条件){
            lock.wait();
        }
    }
    
    //
    synchronized(lock){
       lock.notifyAll();
    }
    

异步模式之生产者和消费者

  • 保护性暂停中的,是线程相互一一对应的;
  • 当不需要生产结果和消费者的线程一一对应的时候;
  • 消息队列,有容量:jdk中各种阻塞的模式;

同步模式之顺序控制:

  • 固定顺序执行【等待标记位,进行判断】;
    • wait-notify,wait-signal【类:ReentrantLock】,可被中断;
    • park-unpark【类:LockSupport】,不可被中断;
  • 交替输出【等待标记int】:
    • wait-notifyAll,wait-signal【ReentrantLock,在Monitor上进行扩展】;
    • Condition-wait-signal【唤醒对应WaitSet】
    • park-unpark【lockSupport】,以线程为操作单位

同步模式之Balking【犹豫】

  • 单例模式之懒汉模式【存在线程安全问题】:

  • 需要双重判断 + 互斥:

    //多线程问题,必须保证instance的可见性,必须是volatile变量;
    if(instance == null) {
        synchronized(类名.class) {
            if (instance == null) {
                instance = new 构造器();
            }
        }
    }
    else {
        return instance;
    }
    
  • synchronized代码块中的代码会局部进行指令重排,当构造方法的执行和对象赋值语句进行重排的时,其他线程有可能会拿到一个没执行构造方法的对象【double-checked locking 问题】;

    • 解决办法:给instance变量加上volatile关键字;
    • 而且当不加volatile关键词时,对instance可能不可见;
  • 单例模式的线程安全性【饿汉,懒汉,枚举,静态内部类】:

    • 是final方法,禁止继承,防止子类重写进行覆盖;

    • 当实现序列化,怎么来防止反序列化生成的对象来破坏单例,添加readResovle()方法

      //规定的
      public Object readResovle(){
          return instance;
      }//会将instance当作反序列化的结果进行返回;
      
    • 构造器私有,而且不能防止反射创建;

    • 枚举类不能通过反射来破坏单例;

    • 枚举类可以避免反序列化的来破坏单例,而且无需自己添加readResovle()方法;

享元模式【flyweight pattern】:

  • 保护性拷贝避免了数据的共享,但是也带来数据的大量拷贝;

  • 需要重用数量有限的同一类对象;

  • eg:包装类:

    • Byte,short,Long,Integer【上限可调】:缓存范围[-128, 127],采用静态内部类的懒汉模式;
    • Character 缓存范围:[0, 127];
    • Boolean:true和false;
posted @ 2025-03-24 20:53  烟雨断桥  阅读(3)  评论(0)    收藏  举报