java并发 使用ScheduledExecutor的温室控制器--thinking in java 21.7.5
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 */
java并发 使用ScheduledExecutor的温室控制器--thinking in java 21.7.5的更多相关文章
- 《Java并发编程实战》第十六章 Java内存模型 读书笔记
Java内存模型是保障多线程安全的根基,这里不过认识型的理解总结并未深入研究. 一.什么是内存模型,为什么须要它 Java内存模型(Java Memory Model)并发相关的安全公布,同步策略的规 ...
- java 并发原子性与易变性 来自thinking in java4 21.3.3
java 并发原子性与易变性 具体介绍请參阅thinking in java4 21.3.3 thinking in java 4免费下载:http://download.csdn.net/deta ...
- java并发编程(十五)----(线程池)java线程池简介
好的软件设计不建议手动创建和销毁线程.线程的创建和销毁是非常耗 CPU 和内存的,因为这需要 JVM 和操作系统的参与.64位 JVM 默认线程栈是大小1 MB.这就是为什么说在请求频繁时为每个小的请 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发基础常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.欢迎 Sta ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- Java并发编程的艺术笔记(五)——Java中的锁
一.Lock接口的几个功能: 显示的获取和释放锁 尝试非阻塞的获取锁 能被中断的获取锁 超时获取锁 使用方式: Lock lock = new ReentrantLock(); lock.lock() ...
- 《Java并发编程的艺术》第5章 Java中的锁 ——学习笔记
参考https://www.cnblogs.com/lilinzhiyu/p/8125195.html 5.1 Lock接口 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同 ...
- 转:【Java并发编程】之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17348313 happen-before规则介绍 Java语言中有一个"先行发生 ...
- 那些年读过的书《Java并发编程实战》十、再探究Java内存模型
1.什么是内存模型,为什么需要它? (1)内存模型的发展背景 近几年计算性能通过重排序实现了很大的提升,而且处理器也越来越朝着多核处理器发展以实现硬件的并行性.随着处理器的不断强大,编译器也在不断的改 ...
随机推荐
- loadrunner_analysis技巧_filter和group by
很多时候要对loadrunner的收集结果进行一些选择性的过滤,比如我们使用阶梯式增加用户的方式,在初期vu没有全部准备好的情况下,此时的曲线不能体现实际情况,所以我们可以用 filter这个工具来帮 ...
- [杂题]CSUOJ1413 Area of a Fractal
题目链接 题意:题中给了图,所以不看字大概也知道 求的是第n个图形的面积. 就是找规律 递推 一类的... 先给结论: 很鬼畜的公式: $\displaystyle\frac{3\times ...
- [unity菜鸟] 笔记1 —— 函数篇
SendMessage() 调用其他物体中的指令,先在脚本中编写一个自定义的函数,然后使用SendMessage()命令来调用那个物体上的命令 //①将以下函数附给target对象 void Rena ...
- JavaScript实现命令行交互
原文地址: http://www.cnblogs.com/liaoyu/p/js-terminal.html 周末闲着想试试用 JavaScript 模拟命令行交互的功能,希望达到的几个功能点如下: ...
- 分析Java的类加载器与ClassLoader(二):classpath与查找类字节码的顺序,分析ExtClassLoader与AppClassLoader的源码
先回顾一下classpath classpath的作用: classpath的作用是指定查找类的路径:当使用java命令执行一个类(类中的main方法)时,会从classpath中进行查找这个类. 指 ...
- [OJ] Wildcard Matching (Hard)
LintCode 192. Wildcard Matching (Hard) LeetCode 44. Wildcard Matching (Hard) 第二次刷还是被这题虐. 其实就是跪在一个地方, ...
- Reflector+Reflexil 相结合实现对DLL文件修改
在工作过程中,我们有可能遇到这样的问题:公司发给客户的软件包突然报错了,但是你知道哪里报错了,而这个代码已经编译成DLL文件了,源代码不在自己这里.怎么办呢?还好现在有Reflexil插件,这个插件只 ...
- C# XML序列化操作菜单
鉴于之前写的一篇博文没使用XML序列化来操作菜单,而且发现那还有一个问题,就是在XML菜单的某个菜单节点前加上一些注释代码的就不能读取,现在使用XML序列化后可以很方便的读取,故在此写一写. XM ...
- 小图用 imageNamed: 大图用 dataWithContentsOfFile:options
1down voteaccepted If you're loading images like:[UIImage imageNamed:@"myImage.png"];Then ...
- Linux中ifreq 结构体分析和使用 及其在项目中的简单应用
[基础知识说明] 结构原型: /* * Interface request structure used for socket * ioctl's. All interface ioctl's mu ...