Efficiently monitor an int value - java

I changed the code to a much more detailed version so you can get a better idea of my problem.
I need to "watch" an integer value and immediately respond to when it changes. So far the best way I've found is using a thread in an infinite loop.
The following is a vastly simplified portion of my project. To summarize, notificationValue is set to 1 by a click of a button within my Bubble class. I need the applet to be able to monitor this notificationValue and respond whenever it changes.
Here is my applet:
public class MyApplet extends JApplet
{
Bubble myBubble = new Bubble();
public void run()
{
new Thread(
new Runnable() {
public void run() {
while(true) {
if(myBubble.getNotificationValue() == 1) {
/* here I would respond to when the
notification is of type 1 */
myBubble.resetNotificationValue;
}
else if(myBubble.getNotificationValue() == 2) {
/* here I would respond to when the
notification is of type 2 */
myBubble.resetNotificationValue;
}
else if(myBubble.getNotificationValue() != 2) {
/* if it is any other number other
than 0 */
myBubble.resetNotificationValue;
}
// don't do anything if it is 0
}
}
}).start();
}
}
And here is my class:
public class Bubble extends JPanel
{
public JButton bubbleButton;
public int notificationValue = 0;
public int getNotificationValue()
{
return notificationValue;
}
public void resetNotificationValue()
{
notificationValue = 0;
}
protected void bubbleButtonClicked(int buttonIndex)
{
notificationValue = buttonIndex;
}
public Bubble()
{
bubbleButton = new JButton();
bubbleButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event)
{
bubbleButtonClicked(1);
}
});
}
}
But obviously that keeps the CPU up at 100% and isn't efficient at all. What would be a better way to do this? (Assume I can't change any of the methods responsible for changing the integer.)

immediately respond to when it changes
How "immediate" does that need to be exactly? Adding a Thread.sleep(10) in your while loop would probably bring down your CPU load to near zero.
What would be a better way to do this? (Assume I can't change any of the methods responsible for changing the integer.)
A better way would be not to expose fields directly. A great example for the benefits of encapsulation - having a setter method would make it trivial to implement the observer pattern.

If that int happens to be a property of a JavaBean, you could use a PropertyChangeListener.
However, I suspect that if you need to monitor some integer for a value change you've got a design problem. It'd be better to make sure that integer can only be changed through some method and make sure that method handles the required logic based on the old and new values.

You could use wait/notify. You could use an ExecutorService. A lot depend on whether you can change the code where the integer is set.

Try adding a Thread.sleep(1); to save CPU.

You can check value of your variable time to time to save CPU. Or use pattern Observer

Could you encapsulate the integer in another class, wrap with a setter and getter and add a notification (via an Observer)?

Assuming you can't change the code which actually sets the integer there isn't much you can do. That being said, if you call Thread.yield() at the end of each pass the impact the thread has on the performance of other applications will be minimal.

Related

WakerBehaviour gets blocked by other activities

I am working on a multi-agent system in JADE and use WakerBehaviours to simulate events.
However, in some cases, the WakerBehaviour wakes up much too late which leads to problems. I have tested this in the following code, but the "Im awake"-message always pops up, AFTER the while-loop is completed. how could i avoid this?
public class Test_Agent extends Agent {
protected void setup() {
Tools.prnt(this, "starting waker");
addBehaviour(new TickerBehaviour(this, 1000) {
protected void onTick() {
Tools.prnt(myAgent, "Im awake.");
}
});
int i = 0;
while(i < 100000) {
System.out.println(i+" waiting.");
i++;
}
}
Thanks in advance!
Cheers, Jacek
As far as I know, processing of behaviours starts after setup().
that is why you should move loops inside a behaviour and If you want to handle events during loop, avoid loops and use cycle behaviour (because behaviours is processed in turn).

Exact same code (with multithreading) doesn't work on 2 different computers

I'm working at the moment on a simple Chess A.I. (calculate possible future turns, rate them, chosse the best one, + some tricks so you don't have to calculate every single turn). The code is written in Java and I'm using Netbeans. To make the calculations faster, I use multithreading. The code works roughly like this:
Main function makes first some calculations and then starts 8 threads.
the threads execute the main-calculations
when they finish, they set a boolean value in a boolean array (finished[]) true. This array is in the "main Class" (if you call it like this), where also the main function is.
during all this time the main function is waiting and checking constantly if every value of the finished[] - array is true. If that is the case, it continues it's work.
Now I have a strange problem. The code works perfectly on my PC, but when I run the EXACT same code on my laptop, the main function won't continue its work, after all values of the finished[]-array are true. I already made some changes in the code, so I can try it with different numbers of threads, but the result is always the same.
I have totally no idea what's going on here and would really appreciate it, if someone of you had any answers and/or suggestions!
If you need any more Information just ask, I'll try my best. :)
(Sorry for possible grammar mistakes, english isn't my native language, but I'm trying my best. ;))
So I was asked to show some Code I used in the program:
(Perhaps first a warning, yes I am still a big Noob in Java and this is my first time I work with threads so don't be shocked if you see terrible mistakes I possibly made. xD)
The main Class looks something like this:
public class Chess_ai_20 {
static boolean finished[] = new boolean[8];
Distributor[] Distributors = new Distributor[8];
...
public static void main(String[] args) {
boolean testing=false;
...
//some calculations and other stuff
...
Distributors[0] = new Distributor(...., "0"); //the String "0" will be the thread name.
Distributors[1] = new ...
...
Distributors[7] = new Distributor(...., "7");
for (int i = 0; i < 8; i++) {
Distributoren[i].start();
}
testing=false;
while(testing==false){
if(finished[0]==true && finished[1]==true && ... && finished[7]==true){
testing=true; //That's the point where I get stuck I suppose
}
}
System.out.println("I made it!");
}
public static void setFinished(int i) {
finished[i] = true;
System.out.println("finished [" + i + "] = " + finished[i]);
System.out.println(Arrays.toString(finished)); //To check how many values already are true
}
}
Then we got of course the class "Distributor"
public class Distributor extends Thread {
Thread t;
String threadname;
boolean running=false;
...
Distributor(......, String s) {
threadname=s;
...
...
}
#Override
public void start() {
running=true;
if (t == null) {
t = new Thread(this,threadname);
t.start();
}
}
#Override
public void run() {
if(running){
...
//Do the main calculations etc.
...
//All the Calculations habe been done at this point
Chess_ai_20.setFinished(Character.getNumericValue(threadname.charAt(0))); //Set the value of finished[] true in the main class
running=false;
}
}
}
As others have mentioned, using a Future would be much simpler and easy to understand. Below is a snippet demonstrating how you could rewrite your code. Check out the code in action.
First, you write a Callable to define the task that you want to do.
public class MyCallable implements Callable<Boolean> {
#Override
public Boolean call() {
// Do some job and return the result.
return Boolean.TRUE;
}
}
And then, you submit this task to an Executor. There are a lot of Executors in JDK. You want to go through the Concurrency Tutorial first.
ExecutorService executor = Executors.newFixedThreadPool(Runtime
.getRuntime().availableProcessors());
List<Callable<Boolean>> callables = new ArrayList<>();
for (int counter = 0; counter < 8; counter++) {
callables.add(new MyCallable());
}
List<Future<Boolean>> futures = executor.invokeAll(callables);
for (Future<Boolean> future : futures) {
System.out.println(future.get()); // You'd want to store this into an array or wherever you see fit.
}
executor.shutdown();
Remember that the futures returned by the executor are in the same order as the Callables you submitted (or added) to the Collection (in this case, an ArrayList). So you don't need to worry about returning the index, an ID or even the name of the Thread (if you assigned one) to map the corresponding result.

How to wait for some period of time and after that just return default value?

I have below code which tells me whether my data is PARTIAL or FULL. It works fine most of the time.
public static String getTypeOfData {
DataType type = new SelectTypes().getType();
if (type == DataType.partial || type == DataType.temp) {
return "partial";
}
return "full";
}
But sometimes, this line DataType type = new SelectTypes().getType(); just hangs and it keeps on waiting forever. This code is not in my control as it is developed by some other teams.
What I want to do is if this line DataType type = new SelectTypes().getType(); takes more than 10 second (or any default number of second), my method should return back a default string which can be partial.
Is this possible to do by any chance? Any example will help me to understand better.
I am using Java 7.
The ExecutorService provides methods which allow you to schedule tasks and invoke them with timeout options. This should do what you are after, however, please pay attention since terminating threads could leave your application in an inconsistent state.
If possible, you should contact the owners of the API and ask for clarification or more information.
EDIT: As per your comment, would caching be a possibility? Meaning that on start up, or some other point, you application goes through the SelectTypes and gets their type and stores them. Assuming that these do not change often, you can save them/update them periodically.
EDIT 2: As per your other comment, I cannot really add much more detail. You would need to add a method call which would allow your application to set these up the moment it is launched (this will depend on what framework you are using, if any).
A possible way would be to make the class containing the getTypeOfData() method as a Singleton. You would then amend the class to pull this information as part of its creation mechanism. Lastly, you would then create a Map<String, Type> in which you would throw in all your types. You could use getClass().getName() to populate the key for your map, and what you are doing now for the value part.
If you are not well aware of executor service then the easiest way to achieve this is by using Thread wait and notify mechanism:
private final static Object lock = new Object();
private static DataType type = null;
public static String getTypeOfData {
new Thread(new Runnable() {
#Override
public void run() {
fetchData();
}
}).start();
synchronized (lock) {
try {
lock.wait(10000);//ensures that thread doesn't wait for more than 10 sec
if (type == DataType.partial || type == DataType.temp) {
return "partial";
}else{
return "full";
}
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return "full";
}
private static void fetchData() {
synchronized (lock) {
type = new SelectTypes().getType();
lock.notify();
}
}
You might have to do some little changes to make it work and looks better like instead of creating new thread directly you can use a Job to do that and some other changes based on your requirement. But the main idea remains same that Thread would only wait for max 10 sec to get the response.

Press and hold key programmatically java

Alright, I've searched now for a whole day, but no result. Maybe someone can help it.
I'm trying to generate a key "press and hold" situation in my java program, programmatically. Let me explain the situation:
I listen constantly for an event. Consider 2 events 'A' and 'B'. If event A occurs, I want to press and hold down the keyboard key (X), and if event 'B' occurs, I want to release the key (X). Now the main thing is, this all has to be a side process, so even if A occurs, I can listen for event B.
I've tried making a separate thread, making an infinite loop inside it, pressing the key using 'Robot' in java, but it turned out to be the most inefficient way of achieving this, as it consumes more than 60% of CPU. I've tried achieving this with a state changed, but don't seem to find a way to restrict the key press, to change only when I want it to.
I would appreciate a solution without any infinite loop, if possible, as I am already using 1 to listen for event occurrences. (Suggestions are welcome)
Here is my code for the thread:
public class KeyPress implements Runnable {
public String command;
public void run() {
try {
Robot r = new Robot();
while (true) {
//System.out.println(command);
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
break;
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
The instance of thread is created as usual, in my main class.
Also, if someone can explain this - when I remove or comment out the
System.out.println(command);
statement (as you see in the code), This thread stops working. If I add this, it works. Although this problem is secondary, as it still is a non-feasible solution.
Well, after a long and tiring attempt to solve this problem, I think I might have a solution.
Firstly, I create a thread everytime event 'A' occurs, although its the same as before. When event 'B' occurs, I interrupt the thread, which makes it to exit. Since these events 'A' and 'B' occur alternatively, this works for the CPU usage problem.
Another optimization, and possibly the answer to the problem of having to write print() statement, was I made the variable command as volatile. As explained here, the compiler optimization was most likely the problem I was facing.
Here is the code after these changes:
public class KeyPress implements Runnable {
public volatile String command;
public void run() {
try {
Robot r = new Robot();
while (command.equals("up") && !Thread.currentThread().isInterrupted()) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
}
} catch (Exception e) {
System.out.println(e);
}
}
}
I hope this helps someone, and someone can provide suggestions on how to improve it.
Observer pattern maybe a good solution.
Do not loop in the thread. Use notify and listener mode like this:
Listen to the command:
class RobotObserver implements Observer{
private Robot r = new Robot();
#Override
public void update(Observable o, Object arg) {
String command=arg.toString();
if (command.equals("up")) {
r.keyPress(KeyEvent.VK_UP);
r.delay(20);
r.keyRelease(KeyEvent.VK_UP);
} else if (command.equals("finish")) {
System.out.println(command);
}
}
}
Notify listener:
Observable observable = new Observable();
observable.addObserver(new RobotObserver());
observable.notifyObservers("up");
observable.notifyObservers("finish");
PS: class Observer and Observable are both in package java.util.

Java - Multiple Objects controlled by Timer (for a Game)

I'm currently working on a small game that consisted of a few targets that pop up at random for various amounts of time. The actual game will get it's I/O from a circuit board since the targets are physical.
My problem is that currently I have a java.util.Timer that fire's off every 2 seconds. Once it is triggered a random target will be displayed (which works fine so far). The problem is that I want to display the targets for a random number of seconds between 1-5 whilst the timer is still running and setting off other targets.
I get no errors and the targets display but never disappear. I guess it's some sort of Thread issue and that maybe since I'm using this.* the Target objects are just somehow getting lost in the nether! After searching around the questions here I have come up with this:
public class Target implements Runnable(){
...
public void displayFor(int seconds){
this.display();
Executors.newSingleThreadScheduledExecutor().schedule(this,time,
TimeUnit.SECONDS);
this.setDisplayed(false);
}
#Override
public void run() {
this.destroy();
}
}
Basically the initial game timer (that sets of the Targets display) calls the displayFor(2) method which runs the targets run method after the time passed. The Targets still won't disappear though.
I have tried a number of different ways of doing this like the displayFor() setting off another java.util.Timer and I also had a go at using the Quartz library (which to be honest seemed like overkill anyway) and still can't get it to work. Since there are no error messages I'm really stuck with this one.
I've haven't included a lot of the code because I don't think it's that relevant but if you guys need more information to help just let me know :)
I managed to get it working. Here's the correct code for anyone in a similar situation.
public class Target{
private Timer timer;
...
public void displayFor(int seconds) {
// send the output
BoardInterface.SetDigitalChannel(this.getId());
// calculate the delay
long time = seconds * 1000;
// create a new timer and schedule the new task
timer = new Timer();
timer.schedule(new TargetTimer(this), time);
this.setDisplayed(true);
}
}
class TargetTimer extends TimerTask{
Target target;
public TargetTimer(Target t){
this.target = t;
}
#Override
public void run() {
target.destroy();
}
}
Not sure if this is a good way of doing it but it works. If you notice anything that could be improved please let me know. Thanks guys!
Perhaps you should tell us what the display method does.
Are you un-displaying the target in the destroy/destructor code?
I'd recommend, instead of void display():
public void setDisplayed(boolean display){
if(display) {
///... do appropriate circuit output to turn on target
} else {
/// ... do appropriate circuit output to turn off target
}
}
and of course
public void run(){
setDisplayed(false);
destroy();
}

Categories

Resources