Run method when multiple conditions fulfilled - java

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.

Related

Why is it "dangerous" to synchronize on method parameter

My IDE (JetBrains IntelliJ IDEA) warns me about synchronizing on a method parameter even when it's always an object.
The full warning reads:
Synchronization on method parameter 's' ... Inspection
info: Reports synchronization on a local variable or parameter. It is
very difficult to guarantee correctness when such synchronization is
used. It may be possible to improve code like this by controlling
access through e.g. a synchronized wrapper class, or by synchronizing
on a field.
My guess is that with auto-boxing, the parameter might be a primitive which gets converted to an object? Although, with auto-boxing, I would assume it's always an object, but maybe not a shared object which means it wouldn't be shared synchronization.
Anyone know why the warning would be present? In my case ShortCircuit type is always an object and the IDE should be able to know that.
The thing is that if you forget to synchronize on ShortCircuit when using it in other places of your code you might get unpredictable results. It's a lot better to synchronize inside the ShortCircuit class so it's guaranteed to be thread safe.
Update
If you're moving the synchronization outside of the class it's inherently unsafe for threading. If you want to synchronize on it externally you will have to audit all places it's used, that's why you get the warning. It's all about good encapsulation. It will be even worse if it is in a public API.
Now if you move the fireFinalCallback method to your ShortCircuit class you can guarantee that the callback won't fire simultaneously. Otherwise you need to have this in mind when calling the methods on that class.
As jontro already mentioned in his answer (and basically, as the warning already says) : This sort of synchronization on the ShortCircuit object does not have the effect that the developer probably hoped to achieve. Unfortunately, the tooltip in your screenshot hides the actual code, but it seems like the code could roughly be
synchronized (s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
That is: It is first checked whether isFinalCallbackFired returns false, and if this is the case, something (hidden) is done, which likely causes the isFinalCallbackFired state to switch to true.
So my assumption is, roughly, that the goal of putting the if statement into the synchronized block was to make sure that doFire is always called exactly once.
And indeed, at this point, the synchronization could be justified. More specifically, and a bit oversimplified:
What can be guaranteed:
When two threads are executing the fireFinalCallback method with the same ShortCircuit parameter, the synchronized block will guarantee that only one thread at a time can check the isFinalCallbackFired state and (if it is false) call the doFire method. So it is guaranteed that doFire will be called only once.
What can not be guaranteed:
When one thread is executing the fireFinalCallback method, and another thread does any operation on the ShortCircuit object (like calling doFire), then this might lead to an inconsistent state. Particularly, if another thread also does
if (!s.isFinalCallbackFired())
{
s.doFire();
}
but without synchronizing on the object, then doFire may be called twice.
The following is an MCVE that illustrates the effect:
public class SynchronizeOnParameter
{
public static void main(String[] args)
{
System.out.println("Running test without synchronization:");
runWithoutSync();
System.out.println();
System.out.println("Running test with synchronization:");
runWithSync();
System.out.println();
System.out.println("Running test with wrong synchronization:");
runWithSyncWrong();
System.out.println();
}
private static void runWithoutSync()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithoutSync(s)).start();
pause(250);
new Thread(() -> fireFinalCallbackWithoutSync(s)).start();
pause(1000);
}
private static void runWithSync()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithSync(s)).start();
pause(250);
new Thread(() -> fireFinalCallbackWithSync(s)).start();
pause(1000);
}
private static void runWithSyncWrong()
{
ShortCircuit s = new ShortCircuit();
new Thread(() -> fireFinalCallbackWithSync(s)).start();
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
private static void fireFinalCallbackWithoutSync(ShortCircuit s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
private static void fireFinalCallbackWithSync(ShortCircuit s)
{
synchronized (s)
{
if (!s.isFinalCallbackFired())
{
s.doFire();
}
}
}
static class ShortCircuit
{
private boolean fired = false;
boolean isFinalCallbackFired()
{
return fired;
}
void doFire()
{
System.out.println("Calling doFire");
pause(500);
fired = true;
}
}
private static void pause(long ms)
{
try
{
Thread.sleep(ms);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
The output is
Running test without synchronization:
Calling doFire
Calling doFire
Running test with synchronization:
Calling doFire
Running test with wrong synchronization:
Calling doFire
Calling doFire
So the synchonized block does make sure that the doFire method is only called once. But this only works if all modifications are only done in the fureFinalCallback method. If the object is modified elsewhere, without a synchronized block, the doFire method may be called twice.
(I'd like to offer a solution for this, but without details about the ShortCircuit class and the remaining classes and processes, one could only give the vague hint to have a look at the java.util.concurrent package and its subpackages: Locks and Conditions might be a viable path, but you have to figure that out...)

Elegant solution for JUnit testing of run method in Thread implementation

I have a class that extends from Thread and want to JUnit test it. At this point I don't want to test for thread-safety, but to merely check whether the implementation logic works fine. My problem is that the run method iterates indefinitely, e.g.:
public void run() {
while (status.isRunning()) {
// do stuff & sleep
}
}
For the purposes of my test, I only want to iterate over the logic in the run method once. The best I came up with to tackle this problem, is a Mockito mock object that uses a static counter and an anonymous implementation of Answer:
private static int counter = 0;
Status status = mock(Status.class);
when(status.isRunning()).thenAnswer(new Answer<Boolean>() {
public Boolean answer(InvocationOnMock invocation) throws Throwable {
if (counter == 0) {
counter++;
return Boolean.TRUE;
}
return Boolean.FALSE;
}
});
I am not sure, whether this solution is the best there is. It seems a bit long-winded for a use case that common.
Can anybody think of a simpler, more elegant solution to the problem?
You don't need to do anything magical, just provide more than one "answer" in the "thenReturn" method, for example...
when(status.isRunning()).thenReturn(true, false);

How does java read code?

Well, I was wondering how java handles code reading and running, for example if I wrote:
static void doSomething(){
doSomethingElse();
doYetAnotherThing();
}
Will it wait for doSomethingElse() to complete before it runs doYetAnotherThing()? Or will it just run both?
I guess if it sets a variable, variable = setAVariable(); it will retrieve the variable before continuing, but if the method contains an infinite loop it would get stuck.
Java will run your code sequentially unless u tell it otherwise (by creating threads.)
If you jave an infinite loop in function doSomthingElse() then doYetAnotherThing() will never execute and doSomething will never terminate.
public static void main(String[] args)
{
doSomethingElse();
doYetAnotherThing();
}
private static void doYetAnotherThing() {
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
System.out.println("Hi");
while(true) // Infinite Loop
{
}
}
This will print to output:
Hi
But not: Hi Agn.
For making both functions run you need to remove the infinite loop in doSomethingElse().
UPDATE:
However if you cant do that and still want to run the code above, you can use threads:
Main Class:
public class javaworking
{
static MyThread t1, t2;
Thread tc;
public static void main(String[] args)
{
t1 = new MyThread(1);
Thread tc = new Thread(t1);
tc.start();
t2 = new MyThread(2);
tc = new Thread(t2);
tc.start();
}
}
Thread class that contains all your functions:
public class MyThread implements Runnable {
int ch;
public MyThread(int choice)
{
ch = choice;
}
#Override
public void run() {
// TODO Auto-generated method stub
switch(ch)
{
case 1:
doSomethingElse();
break;
case 2:
doYetAnotherThing();
break;
default:
System.out.println("Illegal Choice");
break;
}
}
private static void doYetAnotherThing() {
// TODO Auto-generated method stub
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
// TODO Auto-generated method stub
System.out.println("Hi");
int i = 1;
while(true)
{
System.out.println(i++);
}
}
}
Please note: The code I provided is merely an example. I didn't do any error handling or follow the recommended standards. The code works and that's it.
Logically the program will read top to bottom. And as a programmer that's all you really need to know. However, behind the scenes this may not necessarily be the case. But you're guaranteed the results as if they ran sequentially.
Sometimes your processor will run lines of code that should never even have been executed! This is because of something called branch prediction(which has a nice explanation on this answer, though not java the idea is demonstrated at a lower level).
Again, you can work under the assumption that everything in the same Thread, will execute in written order.
These are synchronous calls executing in one thread so they are executed one after the other, ie. first doSomethingElse(); then doYetAnotherThing();. If you wanted them to be executed concurrently you could put each in different threads, then the order would not be guaranteed.
One listing from the spec is here:
http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html
The gist is that one function must return before the next one is called. I can't say what that means in your case without knowing what your functions are doing. They could return because they finished or because they forked/spawned off another process/thread/async action. There are more subtleties to this but I'm not getting into anything further than this since they over complicate and obfuscate the answer.
Based on the terminology you use, I would suggest starting with a tutorial. Java doesn't read your code. Java is a language. The compiler will 'read' and parse your code, and generate bytecode that will be executed by the JVM.
And yes, if you cause an infinite loop it's a problem and your program won't exit.

Which is the Best way to exit a method

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

How can I interrupt a sequence of procedures in Java?

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

Categories

Resources