Java并发基础(24):Guava Service(服务)介绍

目录

说明

1、Guava里面的服务有五种状态

2、Guava里面已经给提供了三个基础实现类:

1、AbstractExecutionThreadService

AbstractExecutionThreadService常用方法介绍

AbstractExecutionThreadService的使用

2、AbstractScheduledService

AbstractScheduledService方法介绍

AbstractScheduledService的使用

3、ServiceManager

ServiceManager常用方法介绍

ServiceManager的使用


说明

Guava包里的Service框架可以帮助我们把异步操作封装成一个Service服务。让这个服务有了运行状态(我们也可以理解成生命周期),这样我们可以实时了解当前服务的运行状态。同时我们还可以添加监听器来监听服务运行状态之间的变化。

1、Guava里面的服务有五种状态

  • Service.State.NEW: 服务创建状态
  • Service.State.STARTING: 服务启动中
  • Service.State.RUNNING:服务启动完成,正在运行中
  • Service.State.STOPPING: 服务停止中
  • Service.State.TERMINATED: 服务停止完成,结束

       所有的服务都需要实现Service接口,里面包括了服务需要实现的一些基本方法,所以我先对Service的方法做一个基本的介绍.

public interface Service {
	/**
	 * 启动当前服务
	 * 只有当服务的状态是NEW的情况下才可以启动,否则抛出IllegalStateException异常
	 */
	@CanIgnoreReturnValue
	Service startAsync();

	/**
	 * 判断当前服务是否处在运行状态 (RUNNING)
	 */
	boolean isRunning();

	/**
	 * 获取当前服务的状态
	 */
	Service.State state();


	/**
	 * 停止当前服务
	 */
	@CanIgnoreReturnValue
	Service stopAsync();

	/**
	 * 等待当前服务到达RUNNING状态
	 */
	void awaitRunning();

	/**
	 * 在指定的时间内等待当前服务到达RUNNING状态
	 * 如果在指定时间没有达到则抛出TimeoutException
	 */
	void awaitRunning(long timeout, TimeUnit unit) throws TimeoutException;

	/**
	 * 等待当期服务到达TERMINATED状态
	 */
	void awaitTerminated();

	/**
	 * 在指定的时间内等待当前服务达到TERMINATED状态,
	 */
	void awaitTerminated(long timeout, TimeUnit unit) throws TimeoutException;

	/**
	 * 获取服务器失败的原因
	 * 在服务是FAILED的状态的时候调用该函数,否则抛出IllegalStateException异常
	 */
	Throwable failureCause();

	/**
	 * 监听当前服务的状态改变,
	 * executor参数表示,监听回调函数在哪里执行
	 */
	void addListener(Service.Listener listener, Executor executor);
}

那咱们应该怎么来使用Guava里面的Servic.怎么把我们需要实现的异步逻辑包装成服务呢?

2、Guava里面已经给提供了三个基础实现类:

  • AbstractService
  • AbstractExecutionThreadService
  • AbstractScheduledService


1、AbstractExecutionThreadService

       AbstractExecutionThreadService可以帮助我们把一个具体的异步操作封装成Service服务。就是把咱们之前在线程的实现逻辑封装成服务。把之前线程的具体实现逻辑搬到AbstractExecutionThreadService的实现方法run()方法去执行



AbstractExecutionThreadService常用方法介绍

AbstractExecutionThreadService实现了Service,Service的方法在AbstractExecutionThreadService里面都有,关于这些方法我们就不重复介绍。我们介绍下AbstractExecutionThreadService新加的一些其他的方法。如下所示:

public class AbstractExecutionThreadService {

	...
	
	/**
	 * 开始执行我们服务逻辑的时候会调用,我们可以在里面做一些初始化的操作
	 */
	protected void startUp() throws Exception;

	/**
	 * 我们当前服务需要执行的具体逻辑
	 */
	protected abstract void run() throws Exception;

	/**
	 * 服务停止之后会调用的函数,我们可以在里面做 一些释放资源的处理
	 */
	protected void shutDown() throws Exception {}

	/**
	 * 比如在我们run方法里面有一个无线循环,可以在这个方法里面置状态,退出无线循环,让服务真正停止
	 * 调stopAsync函数的时候,会调用该方法
	 */
	protected void triggerShutdown() {}
	
	...
}
  •  AbstractExecutionThreadService类里面最重要的就是run()方法了,这个方法是我们服务需要具体实现的方法,服务需要处理的具体逻辑在这个方法里面做。


AbstractExecutionThreadService的使用

       我们用一个简单的实例来说明。我们自定义一个AbstractExecutionThreadServiceImpl实现AbstractExecutionThreadService,把我们线程的操作的具体逻辑搬到AbstractExecutionThreadServiceImpl里面去做。

public class AbstractExecutionThreadServiceImpl extends AbstractExecutionThreadService {

	private volatile boolean running = true; //声明一个状态

	@Override
	protected void startUp() {
		//TODO: 做一些初始化操作
	}

	@Override
	public void run() {
		// 具体需要实现的业务逻辑,会在线程中执行
		while (running) {
			try {
				// 等待2s
				Uninterruptibles.sleepUninterruptibly(2, TimeUnit.SECONDS);
				System.out.println("do our work.....");
			} catch (Exception e) {
				//TODO: 处理异常,这里如果抛出异常,会使服务状态变为failed同时导致任务终止。
			}
		}
	}

	@Override
	protected void triggerShutdown() {
		//TODO: 如果我们的run方法中有无限循环啥的,可以在这里置状态,让退出无限循环,,stopAsync()里面会调用到该方法
		running = false; //这里我们改变状态值,run方法中就能够得到响应。=
	}

	@Override
	protected void shutDown() throws Exception {
		//TODO: 可以做一些清理操作,比如关闭连接啥的。shutDown() 是在线程的具体实现里面调用的
	}

}
  •   针对AbstractExecutionThreadServiceImpl我们写个测试,看下效果。
	@Test
	public void abstractExecutionThreadServiceTest() {
		// 定义我们自定义的AbstractExecutionThreadServiceImpl的类对象
		AbstractExecutionThreadServiceImpl service = new AbstractExecutionThreadServiceImpl();
		// 添加状态监听
		service.addListener(new Service.Listener() {
			@Override
			public void starting() {
				System.out.println("服务开始启动");
			}

			@Override
			public void running() {
				System.out.println("服务开始运行");
			}

			@Override
			public void stopping(Service.State from) {
				System.out.println("服务关闭中");
			}

			@Override
			public void terminated(Service.State from) {
				System.out.println("服务终止");
			}

			@Override
			public void failed(Service.State from, Throwable failure) {
				System.out.println("失败,cause:" + failure.getCause());
			}
		}, MoreExecutors.directExecutor());
		// 启动服务
		service.startAsync().awaitRunning();
		System.out.println("服务状态为:" + service.state());
		// 等待30s
		Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
		// 停止服务
		service.stopAsync().awaitTerminated();

		System.out.println("服务状态为:" + service.state());
	}
服务开始启动
服务开始运行
服务状态为:RUNNING
do our work.....
do our work.....
do our work.....
服务关闭中
do our work.....
服务终止
服务状态为:TERMINATED



说明:服务启动时即调用startAsync()时会执行run方法。

2、AbstractScheduledService

       AbstractScheduledService可以帮助我们把周期性的任务封装成一个服务
咱们线程池不是也有一个周期性的线程池么,两者是一一对应的.



AbstractScheduledService方法介绍

       AbstractScheduledService也是一个服务,故Service里面的方法AbstractScheduledService也都有,这些方法上面已经提到了.这里着重介绍其他的一些方法.

public class AbstractScheduledService {

	...

	/**
	 * 周期任务的具体逻辑在这个里面实现
	 */
	protected abstract void runOneIteration() throws Exception;

	/**
	 * 启动周期任务之前调用,我们可以在里面做一些初始化的操作
	 */
	protected void startUp() throws Exception;


	/**
	 * 周期任务停止之后调用,我们可以在里面做 一些释放资源的处理
	 */
	protected void shutDown() throws Exception {}


	/**
	 * 指定当前周期任务在哪个ScheduledExecutorService里面调用
	 * Scheduler.newFixedDelaySchedule()
	 */
	protected abstract Scheduler scheduler();

	...
}



AbstractScheduledService的使用

       用一个简单的实例来说明下AbstractScheduledService的使用.自定义一个类继承AbstractScheduledService.实现一个非常简单的周期性任务.

public class AbstractScheduledServiceImpl extends AbstractScheduledService {


	@Override
	protected void startUp() throws Exception {
		//TODO: 做一些初始化操作
	}

	@Override
	protected void shutDown() throws Exception {
		//TODO: 可以做一些清理操作,比如关闭连接啥的。shutDown() 是在线程的具体实现里面调用的
	}

	@Override
	protected void runOneIteration() throws Exception {
		// 每次周期任务的执行逻辑
		try {
			System.out.println("do work....");
		} catch (Exception e) {
			//TODO: 处理异常,这里如果抛出异常,会使服务状态变为failed同时导致任务终止。
		}
	}

	@Override
	protected Scheduler scheduler() {
		// 5s执行一次的Scheduler
		return Scheduler.newFixedDelaySchedule(1, 5, TimeUnit.SECONDS);
	}
}

       单元测试,测试下.

	@Test
	public void abstractScheduledServiceImplTest() {
		// 定义AbstractScheduledServiceImpl对象
		AbstractScheduledServiceImpl service = new AbstractScheduledServiceImpl();
		// 添加状态监听器
		service.addListener(new Service.Listener() {
			@Override
			public void starting() {
				System.out.println("服务开始启动.....");
			}

			@Override
			public void running() {
				System.out.println("服务开始运行");
			}

			@Override
			public void stopping(Service.State from) {
				System.out.println("服务关闭中");
			}

			@Override
			public void terminated(Service.State from) {
				System.out.println("服务终止");
			}

			@Override
			public void failed(Service.State from, Throwable failure) {
				System.out.println("失败,cause:" + failure.getCause());
			}
		}, MoreExecutors.directExecutor());
		// 启动任务
		service.startAsync().awaitRunning();
		System.out.println("服务状态为:" + service.state());

		// 等待30s
		Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);

		// 关闭任务
		service.stopAsync().awaitTerminated();
		System.out.println("服务状态为:" + service.state());
	}



3、ServiceManager

       ServiceManager是用来管理多个服务的,让对多个服务的操作变的更加容易,比如咱们可以同时去启动多个服务,同时去停止多个服务等等.



ServiceManager常用方法介绍

public class ServiceManager {

	/**
	 * 构造函数,管理多个Service服务
	 */
	public ServiceManager(Iterable<? extends Service> services);

	/**
	 * 给ServiceManager增加状态监听器
	 */
	public void addListener(Listener listener, Executor executor);
	public void addListener(Listener listener);

	/**
	 * 开始启动ServiceManager里面所有Service服务
	 */
	public ServiceManager startAsync();

	/**
	 * 等待ServiceManager里面所有Service服务达到Running状态
	 */
	public void awaitHealthy();
	public void awaitHealthy(long timeout, TimeUnit unit) throws TimeoutException;

	/**
	 * 停止ServiceManager里面所有Service服务
	 */
	public ServiceManager stopAsync();

	/**
	 * 等待ServiceManager里面所有Service服务达到终止状态
	 */
	public void awaitStopped();
	public void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException;

	/**
	 * ServiceManager里面所有Service服务是否都达到了Running状态
	 */
	public boolean isHealthy();

	/**
	 * 以状态为索引返回当前所有服务的快照
	 */
	public ImmutableMultimap<State, Service> servicesByState();

	/**
	 * 返回一个Map对象,记录被管理的服务启动的耗时、以毫秒为单位,同时Map默认按启动时间排序
	 */
	public ImmutableMap<Service, Long> startupTimes();

}



ServiceManager的使用

       我们用一个简单的实例,来管理咱们上面实现的AbstractExecutionThreadServiceImpl和AbstractScheduledServiceImpl类.代码如下.

    @Test
    public void serviceManagerTest() {
        // 定义两个服务
        AbstractExecutionThreadServiceImpl service0 = new AbstractExecutionThreadServiceImpl();
        AbstractScheduledServiceImpl service1 = new AbstractScheduledServiceImpl();
        List<Service> serviceList = Lists.newArrayList(service0, service1);
        // ServiceManager里面管理这两个服务
        ServiceManager serviceManager = new ServiceManager(serviceList);
        // 添加监听
        serviceManager.addListener(new ServiceManager.Listener() {
            @Override
            public void healthy() {
                super.healthy();
                System.out.println("healthy");
            }

            @Override
            public void stopped() {
                super.stopped();
                System.out.println("stopped");
            }

            @Override
            public void failure(Service service) {
                super.failure(service);
                System.out.println("failure");
            }
        });
        // 启动服务,等待所有的服务都达到running状态
        serviceManager.startAsync().awaitHealthy();
        // 等待30s
        Uninterruptibles.sleepUninterruptibly(30, TimeUnit.SECONDS);
        // 停止服务
        serviceManager.stopAsync().awaitStopped();
    }
public class AbstractExecutionThreadServiceImpl extends AbstractExecutionThreadService {

    private volatile boolean running = true;

    @Override
    protected void startUp() throws Exception {
        super.startUp();
        System.out.println("startUp()...初始化");
    }

    @Override
    protected void run() throws Exception {
        //业务逻辑
        while(running){
            try {
                Uninterruptibles.sleepUninterruptibly(2, TimeUnit.SECONDS);
                System.out.println("run() ...do our work....");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void shutDown() throws Exception {
        super.shutDown();
        System.out.println("shutDown()...关闭连接");
    }

    //stopAsync()里面会调用到该方法
    @Override
    protected void triggerShutdown() {
        super.triggerShutdown();
        running = false;
        System.out.println("triggerShutdown()...改变状态值");
    }

//    @Test
//    public void abstractExecutionThreadServiceTest(){
     public static void main(String[] args) {
        AbstractExecutionThreadServiceImpl service = new AbstractExecutionThreadServiceImpl();
        // 添加状态监听
        service.addListener(new Service.Listener() {
            @Override
            public void starting() {
                System.out.println("starting()...服务开始启动");
            }

            @Override
            public void running() {
                System.out.println("running()...服务开始运行");
            }

            @Override
            public void stopping(Service.State from) {
                System.out.println("stopping()...服务关闭中");
            }

            @Override
            public void terminated(Service.State from) {
                System.out.println("terminated()...服务终止");
            }

            @Override
            public void failed(Service.State from, Throwable failure) {
                System.out.println("失败,cause:" + failure.getCause());
            }
        }, MoreExecutors.directExecutor());
        /**
         *   startAsync()启动当前服务
         * 只有当服务的状态是NEW的情况下才可以启动,否则抛出IllegalStateException异常
         *   awaitRunning()等待当前服务到达RUNNING状态
         */
        service.startAsync().awaitRunning();
        System.out.println("服务状态:"+service.state());
        //等待30s
        Uninterruptibles.sleepUninterruptibly(10,TimeUnit.SECONDS);
         // 停止服务
        service.stopAsync().awaitTerminated();
         System.out.println("服务状态:"+service.state());
    }
}
//starting()...服务开始启动
//startUp...初始化
//running()...服务开始运行
//服务状态:RUNNING
//run() ...do our work....
//run() ...do our work....
//run() ...do our work....
//run() ...do our work....
//triggerShutdown()...改变状态值
//stopping()...服务关闭中
//run() ...do our work....
//shutDown()...关闭连接
//terminated()...服务终止
//服务状态:TERMINATED
public class AbstractScheduledServiceImpl extends AbstractScheduledService {

    @Override
    protected void startUp() throws Exception {
        super.startUp();
        System.out.println("startUp()...初始化操作");
    }

    @Override
    protected void shutDown() throws Exception {
        super.shutDown();
        System.out.println("shutDown()...关闭连接");
    }

    @Override
    protected void runOneIteration() throws Exception {
        // 每次周期任务的执行逻辑
        try {
            System.out.println("runOneIteration()...do work....");
        } catch (Exception e) {
            //TODO: 处理异常,这里如果抛出异常,会使服务状态变为failed同时导致任务终止。
        }
    }

    @Override
    protected Scheduler scheduler() {
        // 5s执行一次的Scheduler
        System.out.println("scheduler()...周期调度");
        return Scheduler.newFixedDelaySchedule(1,5, TimeUnit.SECONDS);
    }

    public static void main(String[] args) {
        AbstractScheduledServiceImpl service = new AbstractScheduledServiceImpl();
        service.addListener(new Service.Listener(){
            @Override
            public void starting() {
                System.out.println("starting()...服务开始启动.....");
            }

            @Override
            public void running() {
                System.out.println("running()...服务开始运行");
            }

            @Override
            public void stopping(Service.State from) {
                System.out.println("stopping()...服务关闭中");
            }

            @Override
            public void terminated(Service.State from) {
                System.out.println("terminated()...服务终止");
            }

            @Override
            public void failed(Service.State from, Throwable failure) {
                System.out.println("failed()...失败,cause:" + failure.getCause());
            }
        }, MoreExecutors.directExecutor());

        // 启动任务
        service.startAsync().awaitRunning();
        System.out.println("服务状态为:" + service.state());

        // 等待30s
        Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);

        // 关闭任务
        service.stopAsync().awaitTerminated();
        System.out.println("服务状态为:" + service.state());
    }

}
public class ServiceManagerTest {

    @Test
    public void serviceManagerTest() {
        // 定义两个服务
        AbstractExecutionThreadServiceImpl service1 = new AbstractExecutionThreadServiceImpl();
        AbstractScheduledServiceImpl service2 = new AbstractScheduledServiceImpl();
        List<Service> services = Lists.newArrayList(service1, service2);
      // ServiceManager里面管理这两个服务
        ServiceManager serviceManager = new ServiceManager(services);
        // 添加监听
        serviceManager.addListener(new ServiceManager.Listener() {
            //调用startAsync()时执行
            @Override
            public void healthy() {
                super.healthy();
                System.out.println("healthy()...healthy");
            }

            @Override
            public void stopped() {
                super.stopped();
                System.out.println("stopped()...stopped");
            }

            @Override
            public void failure(Service service) {
                super.failure(service);
                System.out.println("failure()...failure");
            }
        });

        // 启动服务,等待所有的服务都达到running状态
        serviceManager.startAsync().awaitHealthy();
        // 等待30s
        Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);
        // 停止服务
        serviceManager.stopAsync().awaitStopped();
    }
}
//startUp()...初始化
//startUp()...初始化操作
//scheduler()...周期调度
//healthy()...healthy
//runOneIteration()...do work....
//run() ...do our work....
//run() ...do our work....
//run() ...do our work....
//runOneIteration()...do work....
//run() ...do our work....
//triggerShutdown()...改变状态值
//shutDown()...关闭连接
//run() ...do our work....
//shutDown()...关闭连接
//stopped()...stopped

原文:https://tuacy.blog.csdn.net/article/details/94278403?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-16.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-16.base

Guava源码分析——ServiceManager_Desilting's 足迹-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值