WakerBehaviour gets blocked by other activities - java

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).

Related

Issues with Threads. Trying to test a timer that utilizes threads and seem to get stuck in a loop

My TEST creates an instance of SimpleTimer with 1000 as a milliseconds measure to delay the thread by 1 second.
#Test
public void testSimpleTimerAsThread() throws InterruptedException
{
SimpleTimer st = new SimpleTimer(1000);
st.start();
Thread.sleep(250);
for(int x = 0; x<5; x++)
{
assertEquals(x, st.getRound());
Thread.sleep(1000);
}
}
My METHOD
timeChanged() just updates the round number and calls for all observers to update their time.
public void start()
{
for(int r = 0; r<5; r++)
{
try
{
timeChanged();
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
}
}
SimpleTimer extends Thread and implements an interface that doesn't really mess with this code.
When I run this i get the java assertion error saying it expected 0 but was 5 so x never incremented and the round increased by 5.
Your SimpleTimer works in the same thread as the rest, so when you call st.start() what happens is it goes straight there and executes everything, then the rest of your test is executed. You need to put all of your SimpleTimer logic in run method instead of start method and remove start method completely, Thread class already has it implemented in the right way (but keep call to st.start(), it's ok, that's how you start a new Thread). But even then it's not gonna work as expected, but this will actually be concurrency problem, not a mistake. I mean there is a slight possibility that it's gonna work (only sometimes, not always), because of the delays, but relying on delays it's not really a good idea.

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.

Efficiently monitor an int value

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.

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();
}

Return from await() from other method

I’m newbie in Play! and I have one question about asynchronous programming in HTTP.
I have a piece of code like this:
public void someMethod() {
for (int i = 0; i < 100; i++) {
doSomething();
await(someTime);
}
}
This method is invoked by user by sending GET/POST request.
It does some computations (doSomething()) and after that it waits some time.
But: the user has to have ability to “return” from await(someTime) and the loop should continue next iteration without waiting all the “someTime” time.
The example code:
public void nextAwait() {
continueАForLoop();
}
The user invokes nextAwait() method by GET/POST.
If it is invoked, the loop will continue and doSomething() will be (has to be) invoked immediately!
So, is it possible in Play?
Thanks in advance for answers :)
The simple answer to this, is to wait for a shorter period of time, then check some value for user interaction, and then continue waiting.
for example, let's assume your total wait time is 10 seconds
public void someMethod() {
for (int i = 0; i < 100; i++) {
doSomething();
for (int j=0; j<10; j++) {
if (!userInterrupt) await("1s");
}
}
}
So, this breaks your wait down to 1 second chunks, and checks a value to see if the user has interrupted the wait. It means that the user will wait a maximum of 1 second before the processing is released.
I don't know if it works this way but you could try something like that: (You have a field monitor = new Object() somewhere)
synchronized ( this.monitor ) {
this.monitor.wait( someTime );
}
and in the other method you call:
synchronized ( monitor ) {
this.monitor.notifyAll();
}

Categories

Resources