java并发 使用ScheduledExecutor的温室控制器--thinking in java 21.7.5

标签: java 并发 scheduledexecutor | 发表时间:2015-07-20 04:26 | 作者:liangrui1988
出处:http://blog.csdn.net

package org.rui.thread.newc;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 *  温室 控制器
 * @author lenovo
 *
 */
public class GreenhouseScheduler
{
	private volatile boolean light = false;// 光
	private volatile boolean water = false;// 水
	private String thermostat = "Day";// 自动调温器

	public synchronized String getThermostat()
	{
		return thermostat;
	}

	public synchronized void setThermostat(String thermostat)
	{
		this.thermostat = thermostat;
	}

	// 调度程序
	ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(10);

	/**
	 * 
	 * @param event  
	 * @param delay 延迟
	 */
	public void scheduler(Runnable event, long delay)
	{
		
		/**
		 * 建并执行在给定延迟后启用的一次性操作。
		 */
		scheduler.schedule(event, delay, TimeUnit.MILLISECONDS);
	}

	/**
	 * 重复
	 * @param envent
	 * @param initialDelay
	 * @param period 连续执行之间的周期    时间越少 执行的越快
	 */
	public void repeat(Runnable envent, long initialDelay, long period)
	{
		
		/**
		 *  创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay
		 *   后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。
		 */
		scheduler.scheduleAtFixedRate(envent, initialDelay, period,
				TimeUnit.MILLISECONDS);
	}

	/**
	 * inner class 
	 * 打开 灯
	 */
	class LightOn implements Runnable
	{

		// put hardware control code here to把硬件控制代码在这里
		// physically turn on the light. 身体开灯。
		@Override
		public void run()
		{
			//System.out.println("Turning on lights");
			System.out.println("打开电灯");

			light = true;

		}

	}

	/**
	 * 关
	 * @author lenovo
	 *
	 */
	class LightOff implements Runnable
	{

		// put hardware control code here to 把硬件控制代码在这里
		// physically turn off the light. 身关灯。
		@Override
		public void run()
		{
			System.out.println("旋转 关灯 ");
			//			System.out.println("Turning off  light");

			water = true;
		}
	}

	class WaterOn implements Runnable
	{

		@Override
		public void run()
		{
			//System.out.println("Turning greenhouse water on");
			System.out.println("温室水开");

			water = true;

		}

	}

	class WaterOff implements Runnable
	{

		@Override
		public void run()
		{
			System.out.println("温室水关");

			//System.out.println("Turning greenhouse water off");
			water = false;

		}

	}

	/**
	 * 控温器  夜晚
	 * @author lenovo
	 *
	 */
	class ThermostatNight implements Runnable
	{

		@Override
		public void run()
		{
			// put hardware control code here 把硬件控制代码在这里
			//System.out.println("thermostat to night setting");
			System.out.println("自动控温器  夜晚设置");
			setThermostat("Night");

		}
	}

	/**
	 * 白天
	 * @author lenovo
	 *
	 */
	class ThernostatDay implements Runnable
	{

		@Override
		public void run()
		{
			// put hardware control code here
			System.out.println("温室白天 设置");
			//			System.out.println("thermostat to day setting");

			setThermostat("Day");

		}
	}

	/**
	 * 钟
	 * @author lenovo
	 *
	 */
	class Bell implements Runnable
	{

		@Override
		public void run()
		{
			System.out.println("Bing!响铃>>");
		}

	}

	/**
	 * 终止
	 * @author lenovo
	 *
	 */
	class Terminate implements Runnable
	{

		@Override
		public void run()
		{
			System.out.println("Terminate》》结束");
			scheduler.shutdown();
			// must start a separate task to do this job 必须启动一个单独的任务来做这份工作
			// since the scheduler has been shut down 自调度器已经关闭
			new Thread()
			{
				public void run()
				{
					for (DataPoint d : data)
					{
						System.out.println("DataPoint:"+d);
					}
				};
			}.start();

		}
	}

	
	
	/**
	 * 可以持有并显示单个的数据段
	 * @author lenovo
	 *
	 */
	// inner class 
	static class DataPoint
	{
		final Calendar time;
		final float temperature;
		final float humidity;

		/**
		 * @param time
		 * @param temperature
		 * @param humidity
		 */
		public DataPoint(Calendar time, float temperature, float humidity)
		{

			this.time = time;
			this.temperature = temperature;
			this.humidity = humidity;
		}

		public String toString()
		{
			DateFormat fd=new SimpleDateFormat("yyyy/MM/dd hh:mm ss");
			return fd.format(time.getTime())
					+ String.format("temperature:%1$.1f humidity:%2$.2f",
							temperature, humidity);
		}

	}

	// //
	private Calendar lastTime = Calendar.getInstance();
	{
		// adjust data to the half hour 调整数据到半个小时
		lastTime.set(Calendar.MINUTE, 30);
		lastTime.set(Calendar.SECOND, 00);
	}

	private float lastTemp = 65.0f;//
	private int tempDirection = +1;//温度 方位
	private float lastHumidity = 50.0f;//最后的  湿度
	private int humidityDirection = +1;//湿气 方位
	private Random rand = new Random(47);
	List<DataPoint> data = Collections
			.synchronizedList(new ArrayList<DataPoint>());

	
	//被调度的任务,它在每次运行时,都可以产生仿真数据,并将其添加到Greenhouse的list<DataPoint>中
	// ineer class
	class CollectData implements Runnable
	{

		@Override
		public void run()
		{
			System.out.println("CollectData》》》run");
			synchronized (GreenhouseScheduler.this)
			{
				// pretend the interval is longer than it is: 假装间隔时间比是:
				lastTime.set(Calendar.MINUTE,
						lastTime.get(Calendar.MINUTE) + 30);
				// one in 5 chances of reversing the direction:一个在5 扭转方向的机会:
				if (rand.nextInt(5) == 4)
				{
					tempDirection = -tempDirection;// 方向
				}
				// store previous value: 店前一个值:
				lastTemp = lastTemp + tempDirection * (1.0f + rand.nextFloat());
				if (rand.nextInt(5) == 4)
				{
					humidityDirection = -humidityDirection;

				}
				lastHumidity = lastHumidity + humidityDirection
						* rand.nextFloat();
				// calendar must be cloned , otherwise all
				// dataPoints hold references to the same lastTime.
				// for a basic object like calendar,clone() is ok.
				data.add(new DataPoint((Calendar) lastTime.clone(), lastTemp,
						lastHumidity));

			}

		}

	}

	// //////////////main
	public static void main(String[] args)
	{
		GreenhouseScheduler gh = new GreenhouseScheduler();
		
		//延迟多少时间  关闭
		gh.scheduler(gh.new Terminate(), 5000);
		
		// former restart class not necessary:前重启类没有必要:
		gh.repeat(gh.new Bell(), 0, 1000);//响铃
		gh.repeat(gh.new ThermostatNight(), 0, 2000);//夜晚  2秒执行
		
		gh.repeat(gh.new LightOn(), 0, 200);//灯
		gh.repeat(gh.new LightOff(), 0, 400);

		gh.repeat(gh.new WaterOn(), 0, 600);//水
		gh.repeat(gh.new WaterOff(), 0, 800);
//
	    gh.repeat(gh.new ThernostatDay(), 0, 1400);//白天
		gh.repeat(gh.new CollectData(), 500, 500);

	}
}
/***
 * output:
 * Bing!响铃>>
自动控温器  夜晚设置
打开电灯
旋转 关灯 
温室水开
温室水关
温室白天 设置
打开电灯
打开电灯
旋转 关灯 
CollectData》》》run
温室水开
打开电灯
打开电灯
旋转 关灯 
温室水关
Bing!响铃>>
打开电灯
CollectData》》》run
打开电灯
温室水开
旋转 关灯 
打开电灯
温室白天 设置
CollectData》》》run
打开电灯
温室水关
旋转 关灯 
打开电灯
温室水开
Bing!响铃>>
CollectData》》》run
旋转 关灯 
打开电灯
自动控温器  夜晚设置
打开电灯
打开电灯
旋转 关灯 
温室水开
温室水关
CollectData》》》run
打开电灯
打开电灯
旋转 关灯 
温室白天 设置
打开电灯
CollectData》》》run
温室水开
Bing!响铃>>
旋转 关灯 
温室水关
打开电灯
打开电灯
CollectData》》》run
旋转 关灯 
温室水开
打开电灯
打开电灯
Bing!响铃>>
自动控温器  夜晚设置
旋转 关灯 
温室水关
CollectData》》》run
打开电灯
打开电灯
温室水开
温室白天 设置
打开电灯
旋转 关灯 
CollectData》》》run
打开电灯
打开电灯
温室水关
温室水开
旋转 关灯 
Bing!响铃>>
打开电灯
CollectData》》》run
Terminate》》结束
DataPoint:2015/07/19 09:00 00temperature:66.4 humidity:50.05
DataPoint:2015/07/19 09:30 00temperature:68.0 humidity:50.47
DataPoint:2015/07/19 10:00 00temperature:69.7 humidity:51.42
DataPoint:2015/07/19 10:30 00temperature:70.8 humidity:50.87
DataPoint:2015/07/19 11:00 00temperature:72.0 humidity:50.32
DataPoint:2015/07/19 11:30 00temperature:73.2 humidity:49.92
DataPoint:2015/07/20 12:00 00temperature:71.9 humidity:49.81
DataPoint:2015/07/20 12:30 00temperature:70.1 humidity:50.25
DataPoint:2015/07/20 01:00 00temperature:68.9 humidity:51.00
DataPoint:2015/07/20 01:30 00temperature:67.7 humidity:50.21

 */


作者:liangrui1988 发表于2015/7/19 20:26:22 原文链接
阅读:78 评论:0 查看评论

相关 [java 并发 scheduledexecutor] 推荐:

java并发 使用ScheduledExecutor的温室控制器--thinking in java 21.7.5

- - CSDN博客编程语言推荐文章
private volatile boolean light = false;// 光. private volatile boolean water = false;// 水. private String thermostat = "Day";// 自动调温器. * @param delay 延迟.

Java并发编程基础

- - 并发编程网 - ifeve.com
并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力. 如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善. 现代的PC都有多个CPU或一个CPU中有多个核. 是否能合理运用多核的能力将成为一个大规模应用程序的关键. 进程是以独立于其他进程的方式运行的,进程间是互相隔离的.

java 并发编程 synchronized

- - Java - 编程语言 - ITeye博客
同步原语--synchronized. synchronized(class)很特别,它会让另一个线程在任何需要获取class做为monitor的地方等待.class与this做为不同的监视器可以同时使用,不存在一个线程获取了class,另一个线程就不能获取该class的一切实例.. ->线程各自获取monitor,不会有等待..

Java并发工具类CyclicBarrier

- - CSDN博客编程语言推荐文章
CyclicBarrier同步屏障. java并发工具类中有一个叫做CyclicBarrier的类,与CountDownLatch类似,都可以实现线程间的同步,但是差别是CyclicBarrier是可重置的同步屏障. 想象一个场景,有N个人不同时间走到一扇门,因为门需要N个人合力才能推开,所以人不足N个时,只能阻塞在此,等到N个人都到了之后,可以推开门,继续进行之前的工作.

Java并发编程【1.2时代】

- - 并发编程网 - ifeve.com
         本文介绍了Java原生的多线程技术(1.2),通过详细介绍wait和notify相关的机制、基础的多线程技术以及基于这些技术的等待超时、线程间的通信技术和线程池高阶技术,最后通过一个基于线程池的简单文本web服务器—MollyServer,来阐明多线程带来好处. 通过介绍这些技术,展示了在没有使用Java并发包的时代(1.5-)是如何完成Java的多线程编程,为理解Java5提供了良好帮助.

java web开发 高并发处理

- - 企业架构 - ITeye博客
java web开发 高并发处理. java处理高并发高负载类网站中数据库的设计方法(java教程,java处理大量数据,java高负载数据). 一:高并发高负载类网站关注点之数据库. 没错,首先是数据库,这是大多数应用所面临的首个SPOF. 尤其是Web2.0的应用,数据库的响应是首先要解决的. 一般来说MySQL是最常用的,可能最初是一个mysql主机,当数据增加到100万以上,那么,MySQL的效能急剧下降.

JAVA并发总结-基础篇

- - CSDN博客编程语言推荐文章
java中有几种方法可以实现一个线程. 继承Thread类,实现Runnable接口创建一个线程的唯一方法是实例化java.lang.Thread类(或其子类),并调用其start()方法. 调用ThreadInstanceA.inerrupt()方法,这样当A线程在Thread的sleep,join方法,或者Object的wait方法的时候会直接抛出InerruptedException,捕捉后便可退出.

Java 多线程 (并发)总结

- - CSDN博客推荐文章
《进程与线程的一个简单解释》 简单摘要如下. 电力有限,一次只能供给一个车间使用. 进程的内存是共享的,每个线程都能使用. 一个线程使用内存空间时,其他线程必须等它结束. 车间厕所,有人时其他人不能进入. 某内存空间,仅供固定数目线程使用. 挂N把锁,进入的人拿钥匙锁上,出来时放回. (1)Runnable接口  (通常选择这种,接口本身可以实现多重继承,比较灵活).

Java:线程并发工具类

- - CSDN博客编程语言推荐文章
一、CountDownLatch . 在实际多线程并发开发过程中,我们会碰见很多等待子线程完毕后在继续执行的情况,(如多个子线程下载文件,所有子线程执行完毕后再重命名为文件名). CountDownLatch的构造函数接受一个int类型的参数作为计数器,调用countDwon()方法,计数器减1,await()方法阻塞当前线程,直到计数器变为0;、 .

构建高性能高并发Java系统

- scourgen - ITeye博客
异步通信显然可以更快的返回响应. 从实际经验看,对高吞吐服务器更大的好处是,系统中的某一服务出现问题后往往出现雪崩似的服务宕机. 这很多都是由于采用同步通信,需要等待其他服务同步通信结束后,其占用资源才能得到释放. 而这些资源往往是socket连接、线程、数据库连接等比较重的资源. 如果你真的需要他,可以用个mock同步.