输入输出
System.out.println("text");
Scanner input = new Scanner(System.in);
double num = input.nextDouble();
extends MIDlet
public class T1Exercise1 extends MIDlet{
@Override
public void startApp() { // 相当于主函数入口
System.out.println("Running startApp …"); // 输出
destroyApp(true);
}
@Override
public void destroyApp(boolean unconditional) {
System.out.println("Running destroyApp …");
notifyDestroyed(); // 终止 MIDlet
}
}
修饰符 private static final
public class Thermometer {
private static final double BASE_TEMPERATURE = 25.0;
// 私有:类内访问;
// 静态:无对象也可使用方法,静态方法中引用的外部变量必须声明为静态;
// final:常量
private final Random randomGenerator = new Random(); // 0~1
public double getCurrentTemperature() {
System.out.println("Temp: ");
return BASE_TEMPERATURE + (randomGenerator.nextDouble() - 0.5) * 10 ; // 25±5
}
}
TimerTask
Date
Date now = new Date();
System.out.println("Current Time: " + now);
int hours = Integer.parseInt(now.toString().substring(11, 13));
Calendar
Calendar cal = Calendar.getInstance();
System.out.println("Year : " + cal.get(Calendar.YEAR));
schedule & scheduleAtFixedRate
schedule: periodicity is important
schedule(task, delay)
; 延迟delay后执行schedule(task, delay, time)
; 延迟delay后间隔time周期性执行
scheduleAtFixedRate: time synchronization is more important
public class FieldControl extends MIDlet {
private long DELAY = 15000; // long 型
@Override
public void startApp() {
// 1)设置Timer
Timer timer = new Timer();
// 2)设置TimerTask
TimerTask task_temp = new TakeTemperature(); //extends TimerTask 的类构造方法
// 3)开始任务 timer.schedule(task, 0, DELAY)
timer.schedule(task_temp, 0, DELAY);
}
@Override
public void destroyApp(boolean unconditional) {
}
}
public class TakeTemperature extends TimerTask{
double temperature;
// 必须实现TimerTask的所有abstract方法,这里是run()
@Override
public void run() {
// 获取日期时间
Date now = new Date();
// 直接调用类Thermometer的方法getCurrentTemperature(),该方法需要为static
temperature = Thermometer.getCurrentTemperature();
if(temperature > 38) System.out.println(now + " Temperature " + temperature + " Risk of fire!!!");
else if(temperature < 5) System.out.println(now + " Temperature " + temperature + " Risk of freezing!!!");
else System.out.println(now + " Temperature " + temperature + " Temperature is normal");
}
}
public class Thermometer {
// 静态方法中引用的外部变量必须声明为静态
static double BASE_TEMPERATURE = 32.5;
// 静态方法随机生成温度
static double getCurrentTemperature(){
return BASE_TEMPERATURE + (new Random().nextDouble()) * 10;
}
}
// RunnerInfo 类有int型ID,int型Age,int型RestHR;
// HeartRate 类有方法根据随机生成的训练强度计算心率
public class HeartRate {
// #注意# 类变量
RunnerInfo runner;
// 注意要重载构造函数,根据输入参数修改类变量runner
public HeartRate(RunnerInfo runner) {
this.runner = runner;
}
int getHeartRate(){
int intensity = new Random().nextInt(100);
int maxHR = 220 - runner.getAge();
int heart_rate = (maxHR - runner.getRestHR()) * intensity + runner.getRestHR();
return heart_rate;
}
}
// TakeHeartRate 类继承 TimerTask
public class TakeHeartRate extends TimerTask{
// #注意# 类变量
RunnerInfo runner;
// 注意要重载构造函数,根据输入参数修改类变量runner
public TakeHeartRate(RunnerInfo runner) {
this.runner = runner;
}
@Override
public void run() {
// #注意# 类对象 要使用 new + 构造函数的方法创建
HeartRate heart_rate = new HeartRate(runner);
int runnerHeartRate = heart_rate.getHeartRate();
int maxHR = 220 - runner.getAge();
int runnerMaxHR = ((maxHR - runner.getRestHR()) * 70 ) + runner.getRestHR();
int runnerMinHR = ((maxHR - runner.getRestHR()) * 60 ) + runner.getRestHR();
if (runnerHeartRate > runnerMaxHR){
System.out.println("Runner " + runner.getID() + " is above his/her maximum heart rate.");
}else if(runnerHeartRate < runnerMinHR){
System.out.println("Runner " + runner.getID() + " is below his/her maximum heart rate.");
}
}
}
public class HeartRateTarget extends MIDlet {
private final long DELAY = 40000;
@Override
public void startApp() {
// #注意# 类对象 要使用 new + 构造函数的方法创建
RunnerInfo runner = new RunnerInfo();
runner.setID(1);
runner.setAge(20);
runner.setRestHR(100);
Timer timer = new Timer();
TimerTask task = new TakeHeartRate(runner);
timer.schedule(task, 0, DELAY);
}
@Override
public void destroyApp(boolean unconditional) {
}
}
Threads
Runnable object
implements Runnable
还可以继承其他类
public class mythread implements Runnable{
@Override
public void run(){
try{
// 线程暂停Thread.sleep必须包含在try-catch中
Thread.sleep(5000);
// code...
}catch(InterruptedException ex){
Logger.getLogger(mythread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Extends Thread class
只能继承线程类
public class ForestControl extends MIDlet {
@Override
public void startApp() {
// 创建线程对象
TemperatureSensor temp1 = new TemperatureSensor();
// 设置线程名字
temp1.setName("Temp1");
// 开启线程
temp1.start();
// 另一种创建并运行线程的写法
(new Thread(new TemperatureSensor())).start();
}
@Override
public void destroyApp(boolean unconditional) {
}
}
public class TemperatureSensor extends Thread{
final long DELAY = 15000;
@Override
public void run(){
// 获取该进程的名字
String threadName = Thread.currentThread().getName();
// 可以如MIDlet类一样使用定时器任务
Timer timer = new Timer();
TimerTask task = new TakeTemperature(threadName);
timer.schedule(task, 0, DELAY);
}
}
public class TakeTemperature extends TimerTask{
String sensorName;
// 重载传入线程名字的构造方法
TakeTemperature(String threadName){
sensorName = threadName;
}
@Override
public void run() {
// code...
}
}
join
在th2中调用th1.join():暂停th2,等待th1执行完成后继续
public class ThreadJoin extends MIDlet {
@Override
public void startApp() {
Thread1 th1 = new Thread1();
th1.setName("th1");
th1.start();
Thread2 th2 = new Thread2(th1);
th2.setName("th2");
th2.start();
}
@Override
public void destroyApp(boolean unconditional) {
}
}
public class Thread1 extends Thread{
final static int DELAY = 10000;
@Override
public void run(){
Calendar time;
for (int i=0; i<3; i++) {
try{
time = Calendar.getInstance();
System.out.println(time + " Th1 count " + i);
// 线程暂停
sleep(DELAY);
}
catch(InterruptedException ex){
Logger.getLogger(Thread1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class Thread2 extends Thread{
Thread waitingThread;
// 重构一个可输入参数的构造方法
public Thread2(Thread thread){
waitingThread = thread;
}
@Override
public void run(){
Calendar time;
for (int i=0; i<3; i++) {
try{
time = Calendar.getInstance();
System.out.println(time + " Th2 count " + i);
System.out.println(time + " Th2 is waiting " + i);
// 线程同步 必须包含在try-catch中
waitingThread.join();
time = Calendar.getInstance();
System.out.println(time + " Th1 finished!");
break;
}
catch(InterruptedException ex){
Logger.getLogger(Thread2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
synchronized methods & statements
当一个线程为一个对象执行同步方法时,调用同一对象同步方法的所有其他线程都会阻塞(暂停执行),直到第一个线程完成对该对象的处理
- methods
public class Count{
private int c = 0;
public synchronized void increment(){
c++;
}
public synchronized void decrement(){
c--;
}
}
- statements
public class Count{
private int c = 0;
public void increment(){
synchronized(this);
c++;
}
public void decrement(){
synchronized(this);
c--;
}
}
Callback
// 接口定义了要求实现的方法
public interface Actions {
public void MaxTempReached (double temp);
public void MinTempReached (double temp);
}
// 1)想要在满足条件时得到通知的类必须实现(implements)接口
public class ForestTempControl extends MIDlet implements Actions{
double MAX_TEMP = 38;
@Override
public void startApp() {
TemperatureSensor temp1 = new TemperatureSensor(MAX_TEMP);
temp1.setName("Temp1");
// 2)需要调用addListener方法向ArrayList中添加接口类(当前类),该进程被添加到期望回调的进程列表中
temp1.addListener((Actions)this);
temp1.start();
TemperatureSensor temp2 = new TemperatureSensor(MAX_TEMP);
temp2.setName("Temp2");
// 2)需要调用addListener方法向ArrayList中添加接口类(当前类),该进程被添加到期望回调的进程列表中
temp2.addListener((Actions)this);
temp2.start();
TemperatureSensor temp3 = new TemperatureSensor(MAX_TEMP);
temp3.setName("Temp3");
// 2)需要调用addListener方法向ArrayList中添加接口类(当前类),该进程被添加到期望回调的进程列表中
temp3.addListener((Actions)this);
temp3.start();
}
// 1)需要实现接口中的所有方法
@Override
public void MaxTempReached(double temp) {
System.out.println("Irrigation Pumps must be opened");
}
@Override
public void MinTempReached(double temp) {
System.out.println("No actions required");
}
@Override
public void destroyApp(boolean unconditional) {
}
}
// 3)线程需要有一个ArrayList<>变量,保存期望收到回调的类。
// 4)线程需要实现添加类到ArrayList<>的函数。
public class TemperatureSensor extends Thread{
final long DELAY = 15000;
double maxTemp;
ArrayList<Actions> listeners; // ArrayList<>的<>中填写接口
// 3)在其构造方法中保存需要的变量和创建ArrayList<>实例
public TemperatureSensor(double maxTemp){
listeners = new ArrayList<>(); // 创建ArrayList<>实例
maxTemp = maxTemp;
}
// 4)实现一个把实现了接口(即期望收到通知的类)添加到ArrayList<>的方法
public void addListener(Actions newListener){
listeners.add(newListener);
}
@Override
public void run(){
String threadName = Thread.currentThread().getName();
Timer timer = new Timer();
TimerTask task = new TakeTemperature(threadName, maxTemp, listeners);
timer.schedule(task, 0, DELAY);
}
}
// 5)满足条件时进行回调
public class TakeTemperature extends TimerTask{
String sensorName;
double temperature;
double maxTemp;
ArrayList<Actions> CurrentListeners;
public TakeTemperature(String threadName, double maxTemp, ArrayList<Actions>listeners){
sensorName = threadName;
maxTemp = maxTemp;
CurrentListeners = listeners;
}
@Override
public void run() {
Date now = new Date();
temperature = Thermometer.getCurrentTemperature();
if(temperature > maxTemp){
System.out.println(sensorName + " " + now + "Temperature" + temperature + "Risk of fire!!!");
// 通知所有期望收到通知也实现了接口Actions的类
for(Actions c:CurrentListeners){
// 回调由implements Actions接口的类具体实现的解决方案 MaxTempReached
c.MaxTempReached(temperature);
}
}else {
System.out.println(sensorName + " " + now + "Temperature" + temperature + "Temperature is lower than " + maxTemp);
// 通知所有期望收到通知也实现了接口Actions的类
for(Actions c:CurrentListeners){
// 回调由implements Actions接口的类具体实现的解决方案 MinTempReached
c.MinTempReached(temperature);
}
}
}
}
TCP Socket
服务器
String postString = "2222";
// 创建套接字
ServerSocketConnection serverSocket = (ServerSocketConnection)Connector.open("socket://:" + postString);
while(true){
// 接受客户端
SocketConnection connectedSocket = (SocketConnection)serverSocket.acceptAndOpen();
// 创建变量接收客户端消息
BufferedReader read = new BufferedReader(new InputStreamReader(connectedSocket.openInputStream()));
String clientSentence = read.readLine();
// 创建变量向客户端发送消息
PrintStream write = new PrintStream(connectedSocket.openOutputStream(),true);//true:每当写入字节数组、调用println方法之一或写入换行字符或字节('\n')时,都会刷新输出缓冲区
String serverSentence = "hello";
write.write(serverSentence.getBytes());
// 关闭客户端连接
connectedSocket.close();
}
客户端
String serverIPAddress = "192.168.56.1";
String postString = "2222";
// 创建套接字
SocketConnection socket = (SocketConnection) Connector.open("socket://:" + serverIPAddress + ":" + postString);
// 创建变量接收服务器消息
BufferedReader read = new BufferedReader(new InputStreamReader(socket.openInputStream()));
// 创建变量向服务器发送消息
PrintStream write = new PrintStream(socket.openOutputStream(),true);
write.println("hello");
write.flush();
Srting fromServer = write.readLine();
socket.close();