I have a bunch of procedures that need to be executed successively until either they are all executed, or a certain condition is met. Here's the basic code that needs to be executed until a condition is met:
public boolean search()
{
robot.go();
robot.spin();
//etc - around 8 more similar commands (each takes around 2 seconds)
return false; //didn't find what it was looking for
}
So far, the only way that I've thought of doing what I wanted is this:
public boolean search()
{
robot.go(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
robot.spin(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
The false parameter to go() and spin() indicates that they should return immediately, allowing the condition to be checked. However, this approach strikes me as rather inefficient, as the same block of code must be repeated 10 times. Could this be achieved more efficiently with exceptions or concurrent Threads?
Not sure why you are using Thread.yield() - are there other threads executing that you didn't mention? Or maybe I misread the problem.
I think maybe the Command pattern could work here. You would have a RobotCommand interface with an execute method, and an implementation of RobotCommand per command type (go, spin, etc). Then you could construct a RobotAlgorithm as a List of RobotCommand, and have a method executeRobotAlgorithm that iterated over the list, calling execute on each RobotCommand and checking the result of thingFound() after each one.
Edit - oh, I think I get it. Do go and spin kick off threads that change the state of the robot, or something like that?
Edit 2 - in response to your comment, it sounds like the problem here is that you need to be able to return immediately if the robot finds what it's looking for, but the go, spin, etc commands won't do this right now, and you need the ability to keep executing new commands in the meantime. So what I might do here is have two threads - one would be an "executor" thread that would execute your List of RobotCommands one by one, and a "watcher" thread that will repeatedly sleep and poll (check thingFound()). If thingFound() is ever true then you can stop your robot as well as the executor thread, or if the executor gets to the end before thingFound() is true then it can signal as such (if necessary).
Clearly, the while loop can be packaged into its own function:
private boolean isFound()
{
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
robot.go(false);
if (isFound()) return true;
robot.spin(false);
if (isFound()) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
(I don't mind if the conditional is split over two lines; I'd probably do that in production code.)
A better Java programmer than I can tell you whether you can pass 'procedures' around (pointers to functions, in terms of C programming). I suspect you can, but I don't know the syntax and rules. The evidence seems to be that you can't (circa 2004, anyway).
based on Jonathan Leffler's answer:
you can use a Runnable as pointer to the commands
private final Runnable going = new Runnable() {
#Override
public void run() {
robot.go(false);
}
});
private final Runnable spinning = new Runnable {
#Override
public void run() {
robot.spin(false);
}
});
// other commands
private boolean isFoundAfter(Runnable command)
{
command.run();
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
if (isFoundAfter(going)) return true;
if (isFoundAfter(spinning)) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
one further step, if appropriate, put the commands in an array or a List and execute it as a script
...
private boolean executeSearch(Runnable... commands)
{
for (Runnable cmd : commands) {
if (isFoundAfter(cmd)) return true;
}
return false; //didn't find what it was looking for
}
public boolean search() {
return executeSearch(going, spinning /* around 8 more similar commands */);
}
robot can use a Condition object to signal to the controller that it's completed some sub-task or entered a new state:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Condition.html
interesting, for the environment that's in you could probably use and notify() and wait() instead of the more flexible Condition. controller could wait() until the robot decides to release him with notify().
Related
I'm currently creating a java programm where I want to run a method, after two conditions are fulfilled. So right when both conditions are occuring, the method should be called. The only way I can think of handling it is as I added it below, but it doesn't seem like the optimal way to do so.
Here no matter if method1 or method2 is called first, the following method is checking if the other condition is already fulfilledand then runs the method. Since there might be methods that depend on more conditions then two, are there more clearer way to handle it?
My example:
public class Test() {
private boolean condition1 = false;
private boolean condition2 = false;
public void method1(){
condition1 = true;
if(condition2){
run();
}
}
public void method2(){
condition2 = true;
if(condition1){
run();
}
}
public void run(){
//Is run when both conditions are true
}
}
Since there might be methods that depend on more conditions then two
As per the statement above I guess I can assume you might have more than two conditions, and perhaps multiple combinations? In that case you wouldn't want to verify the conditions in your run method.
You could have a dedicated method applying the required conditions as needed, something like this:
public void runIfTheConditionsAreMet() {
if(condition1 && condition2) {
run();
}
}
This way you would have a dedicated method to check for the conditions and call your run method only when necessary, without repeating code in your method1, method2, and you would have a place you could document the conditions (if necessary).
Your code would look a little bit cleaner, as below:
public void method1(){
condition1 = true;
runIfTheConditionsAreMet();
}
public void method2(){
condition2 = true;
runIfTheConditionsAreMet();
}
Ps. Even if you don't intend to have more conditions I think this solution would fit your needs.
If I were to open up this code, and have to understand it, I would have a much easier time if I saw something more like this:
public void run(){
if(condition1 && condition2){
// Now run the important code
}
}
Whatever calls were made to method1 and method2 before would be changed to calls to run(). This seems much more intuitive to me, instead of spreading the check out between two methods, either one of which may execute run().
Take a look at CountDownLatch.
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.
I was looking for the ways to exit a method,
i found two methods
System.exit();
Return;
System.exit() - Exits the full program
Return exits current method and returns an error that remaining code are unreachable.
class myclass
{
public static void myfunc()
{
return;
System.out.println("Function ");
}
}
public class method_test
{
public static void main(String args[])
{
myclass mc= new myclass();
mc.myfunc();
System.out.println("Main");
}
}
There is no best way, it depends on situation.
Ideally, there is no need to exit at all, it will just return.
int a() {
return 2;
}
If there is a real need to exit, use return, there are no penalties for doing so.
void insertElementIntoStructure(Element e, Structure s) {
if (s.contains(e)) {
return; // redundant work;
}
insert(s, e); // insert the element
}
this is best avoided as much as possible as this is impossible to test for failure in voids
Avoid system.exit in functions, it is a major side effect that should be left to be used only in main.
void not_a_nice_function() {
if (errorDetected()) {
System.exit(-1);
}
print("hello, world!");
}
this pseudocode is evil because if you try to reuse this code, it will be hard to find what made it exit prematurely.
The best and proper way to exit from method is adding return statement.
System.exit() will shutdown your programm.
if you use system.exit once a thread goes there, it won't come back.
system.exit is part of Design of the Shutdown Hooks API
first of all your code will kill good programmers imagine this code Which is the Best way to exit a method this code example that how a return comes before a System.out.print(); as it becomes unreachable after the return statement lols
the command
System.exit(int status); (status=0 for Normal Exit && status=-1 for abnormal exit
is only used if you want to exactly quit your whole app whereas
the command
return;
is used to get out/return from a method
these two are different in their operations
Though I know it'll be a bit silly to ask, still I want to inquire more about the technical perspective of it.
A simple example of an infinite loop:
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
How can I interrupt (stop) this infinite loop from outside of this class (e.g., with the help of inheritance)?
I feel dirty even writing this, but...
From a different thread, you could call System.setOut() with a PrintStream implementation, which throws a RuntimeException when you call println().
We can achieve it using volatile variable, which we will change ouside Thread and stop the loop.
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
This is better way to write Infinite Loop.
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
You can get at the thread running the infinite loop from a different thread and call interrupt on it. You'll have to be very sure what you are doing though, and hope that the interrupted thread will behave properly when interrupted.
Here, I've named the thread with the offending loop for easier identification. Beware that the following solution is vulnerable to race conditions.
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
Then in some other class:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
Note that in my example I assume the two threads are in the same ThreadGroup. There is no guarantee that this will be the case, so you might need to traverse more groups.
If you have some control over this, a decent pattern here would be to have while(!isInterrupted()) instead in the loop declaration and use t.interrupt() instead of t.stop().
My only advice to you, even after posting this, is to not do this. You can do it, but you really shouldn't.
I think this is not possible. Only using break within the loop. You could use
while(cond) {}
And from some other place make it false
You can interrupt this thread by keeping its static reference of inherited reference to this Thread [main] by asking from Thread.currentThread(), like this
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
And to terminate you can call this from some other thread
LoopInfinite.main.interrupt();
But it will only work if both threads are part of the same group. Otherwise calling thread will get SecurityException
You cannot stop this from outside of this class. If you use inheritance you can overwrite your loop, but without abort-flag you won't be able to do so.
Very open question, but stopping such loop would most likely require you to operate from another thread. The other thread would then need to set some variable that your infinite loop can check regularly, and if the variable has a certain value; break out of the loop.
You won't be able to interrupt this particular loop without halting the process entirely. In general, if you're trying to do it from an external source (I'm assuming you have no control over the source code, because if you did you could easily set a condition in the loop, such as a boolean you could set from an external Thread), you will have to halt the running Thread, whether you do this through the Thread object (you'll have to find a reference to it somehow, for example by looping through existing Threads), or whether you halt it as a system process.
Another option would be to override the method with a loop that isn't an infinite loop, but unfortunately that doesn't apply to your example because it's a static method.
Your kind of problem looks like a Threading problem. But still, it is now a a good practice to include a stopping flag even in threads
If you need an "infinite" loop, you sure need a thread (else your app will be stuck until the end of the loop).
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
So, this is a simple method to have background running loop.
Add a variable shouldBreak or something which can be set using getter and setter.
public class LoopInfinite {
private boolean shouldBreak = false;
public boolean isShouldBreak() {
return shouldBreak;
}
public void setShouldBreak(boolean shouldBreak) {
this.shouldBreak = shouldBreak;
}
public static void main(String[] args) {
// Below code is just to simulate how it can be done from out side of
// the class
LoopInfinite infinite = new LoopInfinite();
infinite.setShouldBreak(true);
for (;;) {
System.out.println("Stackoverflow");
if (infinite.shouldBreak)
break;
}
}
}
Here is what I did:
while(Exit == false){
Scanner input = new Scanner(System.in);
String in = input.next();
switch(in){
case "FindH":
FindHyp hyp = new FindHyp();
float output = hyp.findhyp();
System.out.println(output);
case "Exit":
Exit = true;
break;
}
}
First, this is a near duplicate of:
How to differentiate when wait(long timeout) exit for notify or timeout?
But it is a new follow-on question.
Having this wait declaration:
public final native void wait(long timeout) throws InterruptedException;
It could exit by InterruptedException, or by timeout, or because Notify/NotifyAll method was called in another thread, Exception is easy to catch but...
My code absolutely needs to know if the exit was from timeout or notify. (In the future, this code needs to be redesigned, but that cannot be done now. So I need to know the reason for the exit from wait.)
Specifically, can someone give an example of using a ThreadLocal Boolean that is set to true only on notify() and where all this is inside an existing loop as shown below? (This was more or less the accepted answer in the other thread, but no specific code example was given. I'm not all that familiar with Java, so I need a specific code example -- ideally in the context of the existing code below.)
public synchronized int getLastSequenceNumber() {
while (empty) {
try {
wait(waitTimeValue);
} catch (InterruptedException e) {}
}
empty = true;
return reportedSequenceNumber;
}
public synchronized void reconcileLastSequenceNumber(int sequenceNumber) {
empty = false;
this.reportedSequenceNumber = sequenceNumber;
notifyAll();
}
the Boolean "empty" serves a purpose outside of the specific question I'm asking here. I believe I will need to add another Boolean to fulfill the suggested answer from the original question. How would I integrate that proposed solution into the existing code snippet above? Thanks.
You might be better off using a Condition (and its await method) rather than built-in monitors, because await returns a boolean value indicating whether the wait timed out.
And even then, you must beware of spurious wakeup (which is indistinguishable from a call to signal.)
You should be using a loop as you currently are anyway, regardless of knowing whether the wait timed out - partly due to the possibility of spurious wakeups. However, I'm not at all sure that you really need to know whether the call exited due to notification or not.
Consider the situation where the notification occurs a nanosecond before the timeout vs the situation where the notification occurs a nanosecond after the timeout. What's the useful difference between the two? Fundamentally there's a race condition if the two occur at "about the same time".
As far as I can tell, wait() really doesn't let you tell whether the call timed out or not, but it shouldn't affect your code. You should be looping and testing something else that is a side-effect of the notification anyway.
It's not clear to me where a ThreadLocal would come into play to be honest - that's exactly the opposite of what you want if you need to be able to tell from the waiting thread whether the notifying the thread has reached a certain point. I don't think you need an extra variable at all - your empty is fine.
There's no direct way to report this with the builtin monitor API, but you could replace the wait() and other functions with a new implementation that tracks this explicitly (untested):
private int wait_ct = 0, signal_ct = 0;
public void checkedNotifyAll() {
synchronized {
signal_ct = wait_ct;
notifyAll();
}
}
public void checkedNotify() {
synchronized {
signal_ct++;
if (signal_ct > wait_ct)
signal_ct = wait_ct;
notify();
}
// Returns true if awoken via notify
public boolean waitChecked(long timeout, int nanos) throws InterruptedException {
synchronized(this) {
try {
wait_ct++;
super.wait(timeout, nanos);
if (signal_ct > 0) {
signal_ct--;
return true;
}
return false;
} finally {
wait_ct--;
if (signal_ct > wait_ct) signal_ct = wait_ct;
notify(); // in case we picked up the notify but also were interrupted
}
}
// Note: Do not combine this with normal wait()s and notify()s; if they pick up the signal themselves
// the signal_ct will remain signalled even though the checkedWait()s haven't been
// awoken, potentially resulting in incorrect results in the event of a spurious wakeup
This isn't necessarily a good way to do this, of course; if you timeout just before notify() is called, the signal condition may be lost, after all. You really should be waiting in a loop, checking some persistent condition.
This is an expanded version based on Jenkov's signal class. An exception is raised if it does not end with a Notify. Thought it might help as I ran into the same problem.
public class MonitorObject{
}
public class Signal{
MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;
public void doWait(int timeOut) throws InterruptedException,TimeoutException{
synchronized(myMonitorObject){
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOut;
Log.d(TAG, String.format("MonitorStart time %d",startTime));
while(!wasSignalled){
long waitTime = endTime - System.currentTimeMillis();
if(waitTime > 0)
myMonitorObject.wait(waitTime);
else{
Log.e(TAG, String.format("Monitor Exit timeout error"));
throw new TimeoutException();
}
}
Log.d(TAG, String.format("MonitorLoop Exit currentTime=%d EndTime=%d",System.currentTimeMillis(),startTime + timeOut));
//Spurious signal so clear signal and continue running.
wasSignalled = false;
}
}
public void doNotify(){
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notify();
}
}
}