【Java】滴答滴答—计时器工具

在多线程编程时,我们需要考虑到资源的有效利用和线程占有资源问题。

例如在C-S框架中,客户机连接服务器的操作。当客户机连接到服务器时,如果长时间没有进行信息交互而一直保持与服务器的连接,这不仅会增加服务器的负担,还会造成CPU资源的浪费。因此,我们完成一个计时器工具,检测当客户机在指定时间内有没有进行操作,如果没有则可以通过调用抽象方法doSomething()来对客户机或相关线程进行关闭或放在缓冲区中等操作,及时归还CPU资源;而当客户机需要进行信息交互时,重新向服务器发送连接请求。

在代码实现上必须要考虑锁和计时器的误差。

我们需要创建两个线程,第一个为本类Didadida下的线程,该线程用来在指定时间内唤醒doSomething()操作;第二个线程作为一个调用业务函数(在计时器时间之外)的线程,其通过内部类来实现,并且刚创建即阻塞,当第一个线程执行notify()时,唤醒该线程并执行doSomething()方法。

执行这两个线程时必须使用同一个对象锁,并且将线程的阻塞和唤醒作为临界资源避免其他线程抢占。

源代码:
 

package com.chy.timer.core;
 
public abstract class Didadida implements Runnable {
    private volatile boolean goon = false;
    private Object lock;
    private long delayTime;
    
    private static final long defaultTime = 1000;
    
    public Didadida() {
        this.lock = new Object();
    }
    
    public abstract void doSomething();
    
    public Didadida setDelayTime(long delayTime) {
        this.delayTime = delayTime;
        return this;
    }
    
    public void start() {
        if (goon == true) {
            return;
        }
        goon = true;
        
        new DidadidaWoker();
        Thread thread = new Thread(this, "com.example.bootDemo.bootstrap.common.Didadida");
        // 设置保护线程,主线程结束了,保护线程也就结束了
        thread.setDaemon(true);
        thread.start();
    }
    
    @Override
    public void run() {
        if (delayTime == 0) {
            delayTime = defaultTime;
        }
        synchronized (lock) {
            try {
                // 指定时间结束后唤醒阻塞线程;
                // 若业务函数所在线程没有在指定时间内完成业务并结束线程;
                // 则本线程的notify()为无效操作,进入下一时间片段。
                lock.wait(delayTime);
                lock.notify();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("守护线程" + Thread.currentThread().getName());
        }
    }
    
    public class DidadidaWoker implements Runnable{
        
        public DidadidaWoker() {
            new Thread(this).start();
        }
        
        @Override
        public void run() {
            while (goon) {
                synchronized (lock) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                doSomething();
                // 业务线程执行完,结束线程,不然会一直在运行
                goon = false;
            }
        }
        
    }

// 扩展了抽象类
public class DidadidaImpl extends Didadida {

    @Override
    public void doSomething() {
        System.out.println("业务线程" + Thread.currentThread().getName());
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值