多线程的设计模式

1. 两阶段终止模式

Two Phase Termination
在线程T1中优雅的终止线程T2,优雅的意思是给线程T1一个料理后事的计划

1.1 错误思路

  • 直接使用stop()来强制杀死线程:这样如果线程锁住了某一个共享资源,他被强制杀死就没有机会释放锁,其他的线程没法获得锁

  • 使用System.exit(int):这个直接杀死了进程,也不是我们想要的

1.2 两阶段终止模式

可以用在:系统的健康状态监控,用一个后台的监控线程来定时监控,当我们需要让他停止就能让他停止

实现的思路就是
① 一个后台监控线程每两秒进行一次监控(while)
② 如果让他停止就让他调用interrupt()方法
③ 如果当前线程正在睡眠,那么调用interrupt()方法会抛出异常,我们在异常设置打断状态为true
④ 如果打断状态为true,则跳出循环终止线程
在这里插入图片描述

class TwoPhaseTermination{
    private Thread monitor;

    //启动线程
    public void start(){
        monitor = new Thread(()->{
           while(true){//每一秒执行一次监控
               Thread current = Thread.currentThread();
               if(current.isInterrupted()){
                   System.out.println("料理后事");
                   break;
               }
               try {
                   Thread.sleep(1000);//sleep的时候被打断会出现异常并且重置打断标记为false
                   System.out.println("执行监控");
               } catch (InterruptedException e) {
                   current.interrupt();//设置打断标记为真
               }
           }
        });
        
        monitor.start();
    }
    //终止线程
    public void stop(){
        monitor.interrupt();
    }
}

2. 生产者消费者模型

  • 消费队列可以用来平衡生产和消费的线程资源
  • 生产者仅仅负责产生数据,不关心数据怎么处理,消费者专心处理结果数据
  • 消息队列是有容量限制的,满时不会再加入数据,空时不会再消耗数据
  • JDK 中各种阻塞队列,采用的就是这种模式
    在这里插入图片描述
class Message {   
        private int id;    
        private Object message;
        public Message(int id, Object message) {      
            this.id = id;     
            this.message = message; 
        }

        public int getId() {    
            return id;    
        }

        public Object getMessage() {   
            return message;
        } 
    }
class MessageQueue {    
    private LinkedList<Message> queue;  
    private int capacity;

    public MessageQueue(int capacity) {   
        this.capacity = capacity;       
        queue = new LinkedList<>();  
    }

    public Message take() { //获取消息
        synchronized (queue) {   
            while (queue.isEmpty()) {   
                log.debug("没货了, wait");  
                try {                
                    queue.wait();     
                } catch (InterruptedException e) {   
                    e.printStackTrace();       
                }         
            }         
            Message message = queue.removeFirst();   
            queue.notifyAll();//唤醒       
            return message;   
        } 
    }

                    
    public void put(Message message) { //存入消息    
        synchronized (queue) {    
            while (queue.size() == capacity) { 
                log.debug("库存已达上限, wait"); 
                try {                 
                    queue.wait();   
                } catch (InterruptedException e) {     
                    e.printStackTrace();       
                }       
            }     
            queue.addLast(message);       
            queue.notifyAll();//唤醒  
        }   
    } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值