Java: Modify & access variable initialized in constructor - java

I have a class.
I initialize a variable in the constructor of that class.
I call a method that contains a while loop and increments the variable each time through.
I wrote a test to check the value of the variable after the method has been called (and goes through the while loop one time).
public class ThreadGenerator implements Runnable {
private int requests;
private int limit;
public ThreadGenerator() {
requests = 0;
}
public void setRequestLimit(int anyLimit) {
this.limit = anyLimit;
}
public void generateThread() {
new Thread(this).start();
}
public void run() {
while(requests < limit) {
try {
// do some stuff
requests++;
// close some stuff
} catch (IOException e) {
e.printStackTrace();
}
}
}
public int getRequests() {
return requests; // calling this method from my tests always returns 0
}
In my test, when I create a new instance of this class, then call this method on that class, it runs correctly and it increments the request counter correctly. I've tried several print statements to make sure of that. But if I call getRequests on my ThreadGenerator object in my test, it will return 0, the amount it was initialized with.
My test code:
ThreadGenerator threadGenerator = new ThreadGenerator();
threadGenerator.setRequestLimit(1);
threadGenerator.generateThread();
assertEquals(threadGenerator.getRequests(), 1);
How can I modify this variable I initialized in the constructor and gain access to it in my test suite?

Bear in mind that just because you ask Java to create a new thread with a Runnable, doesn't mean that the run() method will be called immediately. It's likely the case that the assertEquals is happening before the run happens the first time.
You may want to return the thread and call join in the test on the generated thread, which will ensure that the Thread runs until it dies, possibly with a short timeout.
/* in the system under test */
#VisibleForTesting Thread generateAndReturnThread() {
Thread thread = new Thread(this);
thread.start();
return thread;
}
public void generateThread() {
generateAndReturnThread();
}
/* in the test */
#Test public void yourTest() {
ThreadGenerator threadGenerator = new ThreadGenerator();
threadGenerator.setRequestLimit(1);
// wait up to a second for thread to complete
threadGenerator.generateThreadAndReturn().join(1000);
assertEquals(threadGenerator.getRequests(), 1);
}
Side note: Consider AtomicInteger for your requests class, if multiple threads might modify requests. This will help prevent two different threads from both modifying requests and overwriting one another.

In addition to above answer, consider declaring the variable as volatile, so that you can actually get the latest value after another thread incremented the variable.

Related

Volatile variable in multithreading program in java

Why do primitive variable in multithreading little program, behave as a volatile variable? Please help me in my code.
/**
* Practice with threads problem visibility.
* #author Matevosyan Vardan
* #version 1.0
* created on 21.09.2017
*/
public class VisibilityProblem {
private static int countingVal = 0;
public static int getCountingVal() {
return countingVal;
}
Start in main
public static void main(String[] args) throws InterruptedException {
Thread looperR = new VisibilityProblem.Looper();
Thread listener = new VisibilityProblem.Listener();
listener.start();
looperR.start();
listener.join();
looperR.join();
}
Class to wright and increase counting variable after sleep 500 millisecond
to wait a little, what helps do some staff Listener thread.
public static class Looper extends Thread {
#Override
public void run() {
while (VisibilityProblem.countingVal < 5) {
VisibilityProblem.countingVal++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("increase " + VisibilityProblem.countingVal);
}
}
}
Class to read and assign counting value
public static class Listener extends Thread {
#Override
public void run() {
int localCount = VisibilityProblem.countingVal;
while (localCount < 5) {
if (localCount != VisibilityProblem.countingVal) {
System.out.println("It is " + localCount + " now");
localCount = VisibilityProblem.countingVal;
}
}
}
}
}
Why do primitive variable in multithreading little program, behave as a volatile variable
It depends what you mean by behave as a volatile variable.
If you mean, why are changes made by one thread seen in the second thread ... then the reason is that the JLS allows this.
If you mean, why are changes made by by one thread guaranteed to be seen in the second thread ... then your program does not provide evidence1 of this!!
The difference in visibility semantics between ordinary and volatile variables are:
For a volatile, the changes are guaranteed to be immediately visible.
For an ordinary variable, the changes may be visible immediately, or with a delay, or ... never. Any of those behaviors conforms with the Java Memory Model.
Seeing the changes with ordinary variables when you run the program on one hardware platform with one version of the Java compiler on a computer running with one set of applications running, etc, etc does not mean that you will always see that in all circumstances.
1 - Indeed, it is theoretically impossible to write a program that can do this. But your program could provide evidence that this is not guaranteed ... or that a (hypothetical) guarantee is not being met.

Controlling an instance's state with AtomicBoolean

I need to ensure that a particular start and stop code is executed only once per instance lifecycle, and that the instance cannot be "restarted". Is the following code adequate for a scenario where multiple threads may be acting upon the instance?
public final class MyRunnable {
private final AtomicBoolean active = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
public void start() {
if (closed.get()) {
throw new IllegalStateException("Already closed!");
}
if (active.get()) {
throw new IllegalStateException("Already running!");
}
active.set(true);
// My one-time start code.
// My runnable code.
}
public void stop() {
if (closed.get()) {
throw new IllegalStateException("Already stopped!");
}
if (!active.get()) {
throw new IllegalStateException("Stopping or already stopped!");
}
active.set(false);
// My one-time stop code.
closed.set(true);
}
}
I would go with a single 3-valued status for two reasons.
Firstly, out of the 4 possible values of the active,closed "tuple" only 3 make sense, setting both to true results in a (possibly benign, but nevertheless) invalid state. You may dismiss it as pure pedantry, but a clear design often brings other benefits.
This leads us neatly to the second, scarier reason:
active.set(false);
// <-- what if someone calls start() here?
closed.set(true); //I assume you wanted to set it to true
As you can see from my comment, you've got a vulnerable spot there, someone could conceivably call start() after you've set active to false but before you set closed to true.
Now you may just say "okay, let's swap the two then and set closed first", but then you have to explain why the two would definitely not be reordered by the JVM. And you'll end up with potentially both flags set to true, resulting in the "invalid state" outlined above.
There is another, separate problem here: the pattern you follow is to call get() to check the value and then set() it to something else later. As PetrosP pointed it out, this isn't an atomic operation, you can call start() a 1000 times with all of them seeing active as false. You need to use compareAndSet instead, which is atomic (this is the whole point of the Atomic* classes), and thus guarantees that only one thread can ever advance the status flag.
So let's combine the two, using a single 3-valued status (I've used AtomicInteger for simplicity, but you can use AtomicReference and a true enum) and compareAndSet():
public final class MyRunnable {
private static final int READY_TO_START = 0;
private static final int ACTIVE = 1;
private static final int STOPPED = 2;
private final AtomicInteger status = new AtomicInteger(READY_TO_START);
public void start() {
if (!status.compareAndSet(READY_TO_START, ACTIVE)) {
throw new IllegalStateException("Already started");
}
// My one-time start code.
}
public void stop() {
if (!status.compareAndSet(ACTIVE, STOPPED)) {
throw new IllegalStateException("Can't stop, either not started or already stopped");
}
// My one-time stop code.
}
}
This solution is not sufficient. Consider tis scenario: Two threads go in start() at the same time. One calls active.get() and it gets false returned. Then the second one calls active.get() and it gets false as well. In this case they will both continue. Then the first one will set active to true. The second one at that point will also set active to true, and they will both continue to the rest of the code that should be run once.
A solution could be this:
public final class MyRunnable {
private final AtomicBoolean active = new AtomicBoolean(false);
private final AtomicBoolean closed = new AtomicBoolean(false);
public void start() {
synchronized (this) {
if (closed.get()) {
throw new IllegalStateException("Already closed!");
}
if (active.get()) {
throw new IllegalStateException("Already running!");
}
active.set(true);
}
// My one-time start code.
// My runnable code.
}
public void stop() {
synchronized (this) {
if (closed.get()) {
throw new IllegalStateException("Already stopped!");
}
if (!active.get()) {
throw new IllegalStateException("Stopping or already stopped!");
}
// My one-time stop code.
closed.set(false);
active.set(false);
}
}
}

How do I unit test asynchronous methods nicely?

I'm currently unit testing my asynchronous methods using thread locking, usually I inject a CountDownLatch into my asynchronous component and let the main thread wait for it to reach 0. However, this approach just looks plain ugly, and it doesn't scale well, consider what happens when I write 100+ tests for a component and they all sequentially have to wait for a worker thread to do some fake asynchronous job.
So is there another approach? Consider the following example for a simple search mechanism:
Searcher.java
public class Searcher {
private SearcherListener listener;
public void search(String input) {
// Dispatch request to queue and notify listener when finished
}
}
SearcherListener.java
public interface SearcherListener {
public void searchFinished(String[] results);
}
How would you unit test the search method without using multiple threads and blocking one to wait for another? I've drawn inspiration from How to use Junit to test asynchronous processes but the top answer provides no concrete solution to how this would work.
Another approach:
Just dont start the thread. thats all.
Asume you have a SearcherService which uses your Searcher class.
Then don't start the async SearcherService, instead just call searcher.search(), which blocks until search is finished.
Searcher s = new Searcher();
s.search(); // blocks and returns when finished
// now somehow check the result
Writing unit test for async never looks nice.
It's necessary that the testMyAsyncMethod() (main thread) blocks until you are ready to check the correct behaviour. This is necessary because the test case terminates at the end of the method. So there is no way around, the question is only how you block.
A straightforward approach that does not influence much the productive code is to
use a while loop: asume AsyncManager is the class under test:
ArrayList resultTarget = new ArrayList();
AsyncManager fixture = new AsyncManager(resultTarget);
fixture.startWork();
// now wait for result, and avoid endless waiting
int numIter = 10;
// correct testcase expects two events in resultTarget
int expected = 2;
while (numIter > 0 && resulTarget.size() < expected) {
Thread.sleep(100);
numIter--;
}
assertEquals(expected, resulTarget.size());
productive code would use apropriate target in the constructor of AsyncManager or uses another constructor. For test purpose we can pass our test target.
You will write this only for inherent async tasks like your own message queue.
for other code, only unitest the core part of the class that performs the calculation task, (a special algorithm, etc) you dont need to let it run in a thread.
However for your search listener the shown principle with loop and wait is appropriate.
public class SearchTest extends UnitTest implements SearchListener {
public void searchFinished() {
this.isSearchFinished = true;
}
public void testSearch1() {
// Todo setup your search listener, and register this class to receive
Searcher searcher = new Searcher();
searcher.setListener(this);
// Todo setup thread
searcherThread.search();
asserTrue(checkSearchResult("myExpectedResult1"));
}
private boolean checkSearchResult(String expected) {
boolean isOk = false;
int numIter = 10;
while (numIter > 0 && !this.isSearchFinished) {
Thread.sleep(100);
numIter--;
}
// todo somehow check that search was correct
isOk = .....
return isOk;
}
}
Create a synchronous version of the class that listens for its own results and uses an internal latch that search() waits on and searchFinished() clears. Like this:
public static class SynchronousSearcher implements SearcherListener {
private CountDownLatch latch = new CountDownLatch(1);
private String[] results;
private class WaitingSearcher extends Searcher {
#Override
public void search(String input) {
super.search(input);
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public String[] search(String input) {
WaitingSearcher searcher = new WaitingSearcher();
searcher.listener = this;
searcher.search(input);
return results;
}
#Override
public void searchFinished(String[] results) {
this.results = results;
latch.countDown();
}
}
Then to use it, simply:
String[] results = new SynchronousSearcher().search("foo");
There are no threads, no wait loops and the method returns in the minimal possible time. It also doesn't matter if the search returns instantly - before the call to await() - because await() will immediately return if the latch is already at zero.

Controlling the execution of a method via Threads in Java

I need to have two classes, one class has two methods each of which will take a while to execute completely. The second class is given information which will decide which one of the two methods in the first class will execute. It is important however that if the second class (which will be executing at the same time in its own thread) decides that the other of the two methods should execute, the first class would go straight to executing the other method and not have to wait for the first to finish.
If class A has the two methods and class B is in parallel in a different thread deciding which method to execute then here is an example:
A is executing method 1 which will take a while to return. During the execution of method 1, class B decides method 2 should execute which means class A should immediately stop doing method 1 and go on to execute method 2.
Is this possible? Maybe with interrupts?
thanks
If you make Class A implement runnable and then execute its method by having Class B create a new Thread with an object of type Class A, you can have Class B call the interrupt method on the Class A thread.
Here's an outline of something that should work:
class ClassA implements Runnable {
public volatile boolean switchToOther;
#Override
public void run() {
switchToOther = false;
try {
method1();
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
if (switchToOther) {
method2();
}
}
public void method1() throws InterruptedException {
work();
}
public void method2() throws InterruptedException {
otherWork();
}
}
class ClassB implements Runnable {
#Override
public void run() {
ClassA a = new ClassA();
Thread t = new Thread(a);
t.start();
if (decideToSwitch()) {
a.switchToOther = true;
t.interrupt();
}
}
}
Note:
InterruptedException can happen beyond your control, so you should check it's due to an explicit switch,
the volatile on the switchToOther field used from several threads,
the resetting of the interrupted state, which is standard idiom when catching InterruptedException

When to use synchronized in Java

I hope this is going to be enough information, so here it goes. If you need more info, lemme know in the comments.
I have a class that has two inner classes. The inner classes each have two methods that call a method in the outer class. So, it looks like this:
public OuterClass {
private boolean outerMethodHasBeenCalled = false;
private void outerMethod() {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
private FirstInnerClass {
public void someMethod() {
outerMethod();
}
}
private SecondInnerClass {
public void someOtherMethod() {
outerMethod();
}
}
}
It's important to note that:
This is for an Android app. Instances of FirstInnerClass and SecondInnerClass are passed to a WebView as a JavaScript interface, so someMethod and someOtherMethod can be called at any time, in no particular order.
I currently have a problem with the existing code (without the synchronized keyword) where outerMethod is called pretty much at the exact same time (I print out a log message, and they're timestamped to the 1000th of a second) by different objects. My app then 'does stuff' twice because outerMethodHasBeenCalled is still false when outerMethod was called. This is not okay, and it is exactly what I'm trying to prevent. My app should only 'do stuff' once and only once: the first time outerMethod is called.
It might sound like I have multiple instances of OuterClass, but rest assured that it's only one instance of OuterClass.
It's important that my app 'does stuff' only the first time outerMethod gets called (I hope that's evident by now). All subsequent calls are essentially ignored. Whichever inner class calls outerMethod first -- doesn't matter.
So, is it appropriate to use the synchronized keyword in this case?
Yup, given what you've laid out above, I'd go with:
private synchronized void outerMethod() {
...
}
Note, this will have the side-effect of blocking one of the callers until the outerMethod() completes. If that is acceptable, cool. If the intent is merely that the code in outerMethod() is run once, and it is OK for the second caller not to be delayed if the first caller is running outerMethod(), you might consider:
public OuterClass {
private AtomicBoolean outerMethodHasBeenCalled = new AtomicBoolean();
private void outerMethod() {
if (outerMethodHasBeenCalled.compareAndSet(false, true)) {
// do stuff
}
}
...
See the JavaDoc for AtomicBoolean to grok what is going on there (assuming it is available in Android's Java).
Wrap everything in outerMethod that you want to run only once in a synchronized block:
private void outerMethod() {
synchronized (this) {
if(!outerMethodHasBeenCalled) {
// do stuff
}
outerMethodHasBeenCalled = true;
}
}
That way, the first time the method is called, only one thread will be allowed into the synchronized block at a time. The first one will execute the code in the if statement, then set outerMethodHasBeenCalled to true. The other threads will see that it is true, and skip the if code.

Categories