Java lock/concurrency issue when searching array with multiple threads - java

I am new to Java and trying to write a method that finds the maximum value in a 2D array of longs.
The method searches through each row in a separate thread, and the threads maintain a shared current maximal value. Whenever a thread finds a value larger than its own local maximum, it compares this value with the shared local maximum and updates its current local maximum and possibly the shared maximum as appropriate. I need to make sure that appropriate synchronization is implemented so that the result is correct regardless of how to computations interleave.
My code is verbose and messy, but for starters, I have this function:
static long sharedMaxOf2DArray(long[][] arr, int r){
MyRunnableShared[] myRunnables = new MyRunnableShared[r];
for(int row = 0; row < r; row++){
MyRunnableShared rr = new MyRunnableShared(arr, row, r);
Thread t = new Thread(rr);
t.start();
myRunnables[row] = rr;
}
return myRunnables[0].sharedMax; //should be the same as any other one (?)
}
For the adapted runnable, I have this:
public static class MyRunnableShared implements Runnable{
long[][] theArray;
private int row;
private long rowMax;
public long localMax;
public long sharedMax;
private static Lock sharedMaxLock = new ReentrantLock();
MyRunnableShared(long[][] a, int r, int rm){
theArray = a;
row = r;
rowMax = rm;
}
public void run(){
localMax = 0;
for(int i = 0; i < rowMax; i++){
if(theArray[row][i] > localMax){
localMax = theArray[row][i];
sharedMaxLock.lock();
try{
if(localMax > sharedMax)
sharedMax = localMax;
}
finally{
sharedMaxLock.unlock();
}
}
}
}
}
I thought this use of a lock would be a safe way to prevent multiple threads from messing with the sharedMax at a time, but upon testing/comparing with a non-concurrent maximum-finding function on the same input, I found the results to be incorrect. I'm thinking the problem might come from the fact that I just say
...
t.start();
myRunnables[row] = rr;
...
in the sharedMaxOf2DArray function. Perhaps a given thread needs to finish before I put it in the array of myRunnables; otherwise, I will have "captured" the wrong sharedMax? Or is it something else? I'm not sure on the timing of things..

I'm not sure if this is a typo or not, but your Runnable implementation declares sharedMax as an instance variable:
public long sharedMax;
rather than a shared one:
public static long sharedMax;
In the former case, each Runnable gets its own copy and will not "see" the values of others. Changing it to the latter should help. Or, change it to:
public long[] sharedMax; // array of size 1 shared across all threads
and you can now create an array of size one outside the loop and pass it in to each Runnable to use as shared storage.
As an aside: please note that there will be tremendous lock contention since every thread checks the common sharedMax value by holding a lock for every iteration of its loop. This will likely lead to poor performance. You'd have to measure, but I'd surmise that letting each thread find the row maximum and then running a final pass to find the "max of maxes" might actually be comparable or quicker.

From JavaDocs:
public interface Callable
A task that returns a result and may
throw an exception. Implementors define a single method with no
arguments called call.
The Callable interface is similar to Runnable, in that both are
designed for classes whose instances are potentially executed by
another thread. A Runnable, however, does not return a result and
cannot throw a checked exception.
Well, you can use Callable to calculate your result from one 1darray and wait with an ExecutorService for the end. You can now compare each result of the Callable to fetch the maximum. The code may look like this:
Random random = new Random(System.nanoTime());
long[][] myArray = new long[5][5];
for (int i = 0; i < 5; i++) {
myArray[i] = new long[5];
for (int j = 0; j < 5; j++) {
myArray[i][j] = random.nextLong();
}
}
ExecutorService executor = Executors.newFixedThreadPool(myArray.length);
List<Future<Long>> myResults = new ArrayList<>();
// create a callable for each 1d array in the 2d array
for (int i = 0; i < myArray.length; i++) {
Callable<Long> callable = new SearchCallable(myArray[i]);
Future<Long> callResult = executor.submit(callable);
myResults.add(callResult);
}
// This will make the executor accept no new threads
// and finish all existing threads in the queue
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
// now compare the results and fetch the biggest one
long max = 0;
for (Future<Long> future : myResults) {
try {
max = Math.max(max, future.get());
} catch (InterruptedException | ExecutionException e) {
// something bad happend...!
e.printStackTrace();
}
}
System.out.println("The result is " + max);
And your Callable:
public class SearchCallable implements Callable<Long> {
private final long[] mArray;
public SearchCallable(final long[] pArray) {
mArray = pArray;
}
#Override
public Long call() throws Exception {
long max = 0;
for (int i = 0; i < mArray.length; i++) {
max = Math.max(max, mArray[i]);
}
System.out.println("I've got the maximum " + max + ", and you guys?");
return max;
}
}

Your code has serious lock contention and thread safety issues. Even worse, it doesn't actually wait for any of the threads to finish before the return myRunnables[0].sharedMax which is a really bad race condition. Also, using explicit locking via ReentrantLock or even synchronized blocks is usually the wrong way of doing things unless you're implementing something low level (eg your own/new concurrent data structure)
Here's a version that uses the Future concurrent primitive and an ExecutorService to handle the thread creation. The general idea is:
Submit a number of concurrent jobs to your ExecutorService
Add the Future returned backed from submit(...) to a List
Loop through the list calling get() on each Future and aggregating the result
This version has the added benefit that there is no lock contention (or locking in general) between the worker threads as each just returns back the max for its slice of the array.
import java.util.concurrent.*;
import java.util.*;
public class PMax {
public static long pmax(final long[][] arr, int numThreads) {
ExecutorService pool = Executors.newFixedThreadPool(numThreads);
try {
List<Future<Long>> list = new ArrayList<Future<Long>>();
for(int i=0;i<arr.length;i++) {
// put sub-array in a final so the inner class can see it:
final long[] subArr = arr[i];
list.add(pool.submit(new Callable<Long>() {
public Long call() {
long max = Long.MIN_VALUE;
for(int j=0;j<subArr.length;j++) {
if( subArr[j] > max ) {
max = subArr[j];
}
}
return max;
}
}));
}
// find the max of each slice's max:
long max = Long.MIN_VALUE;
for(Future<Long> future : list) {
long threadMax = future.get();
System.out.println("threadMax: " + threadMax);
if( threadMax > max ) {
max = threadMax;
}
}
return max;
} catch( RuntimeException e ) {
throw e;
} catch( Exception e ) {
throw new RuntimeException(e);
} finally {
pool.shutdown();
}
}
public static void main(String args[]) {
int x = 1000;
int y = 1000;
long max = Long.MIN_VALUE;
long[][] foo = new long[x][y];
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
long r = (long)(Math.random() * 100000000);
if( r > max ) {
// save this to compare against pmax:
max = r;
}
foo[i][j] = r;
}
}
int numThreads = 32;
long pmax = pmax(foo, numThreads);
System.out.println("max: " + max);
System.out.println("pmax: " + pmax);
}
}
Bonus: If you're calling this method repeatedly then it would probably make sense to pull the ExecutorService creation out of the method and have it be reused across calls.

Well, that definetly is an issue - but without more code it is hard to understand if it is the only thing.
There is basically a race condition between the access of thread[0] (and this read of sharedMax) and the modification of the sharedMax in other threads.
Think what happens if the scheduler decides to let no let any thread run for now - so when you are done creating the threads, you will return the answer without modifying it even once! (of course there are other possible scenarios...)
You can overcome it by join()ing all threads before returning an answer.

Related

Why are my threads not synchronizing?

I am trying to get a grasp on synchronizing threads, but I don't understand the problem I'm encountering.
Can someone please help me diagnose this or, even better, explain how I can diagnose this for myself?
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
public class Controller {
public static void main(String[] args) {
int numThreads = 0;
List<Thread> threads = new ArrayList<>();
if (args.length > 0) {
numThreads = Integer.parseInt(args[0]);
}
else {
System.out.println("No arguments");
System.exit(1);
}
CyclicBarrier barrier = new CyclicBarrier(numThreads);
int arr[][] = new int[10][10];
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(new ThreadableClass(barrier, arr));
threads.add(newThread);
}
for (Thread thread : threads) {
thread.start();
}
}
}
There is a main method (above) which accepts the number of threads I want as a command line argument. And there is a work-flow (below) which I am aiming to have increment all elements in a 2D array and print the array before the next thread has its chance to do the same:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ThreadableClass implements Runnable {
private CyclicBarrier barrier;
private int arr[][];
public ThreadableClass(CyclicBarrier barrier, int[][] arr) {
this.barrier = barrier;
this.arr = arr;
}
#Override
public void run() {
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
for (int i = 0; i < 10; i++) {
changeArray();
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
private synchronized void changeArray() {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j]++;
}
}
printArray();
}
private synchronized void printArray() {
System.out.println(Thread.currentThread().getId() + " is printing: ");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
Imagining the size of the array is 2x2, the expected output would look something like this:
1 1
1 1
2 2
2 2
3 3
3 3
4 4
4 4
...
...
(10 * numThreads)-1 (10 * numThreads)-1
(10 * numThreads)-1 (10 * numThreads)-1
(10 * numThreads) (10 * numThreads)
(10 * numThreads) (10 * numThreads)
Instead, all threads increment the array, and begin printing over one another.
There is nothing surprising about the result. You create n threads. You tell all threads to start. Each threads run() starts with:
long threadId = Thread.currentThread().getId();
System.out.println(threadId + " Starting");
...changeArray();
going to change that shared array. After writing to the array, you try to sync (on that barrier). Its too late then!
The point is: you have 10 different ThreadableClass instances. Each one is operating on its own! The synchronized key word ... simply doesn't provide any protection here!
Because: synchronized prevents two different threads calling the same method on the same object. But when you have multiple objects, and your threads are calling that method on those different objects, than there is no locking! What your code does boils down to:
threadA to call changeArray() .. on itself
threadB to call changeArray() .. on itself
threadC to call changeArray() .. on itself
...
In other words: you give n threads access to that shared array. But then you allow those n threads to enter changeArray() at the same time.
One simple fix; change
private synchronized void changeArray() {
to
private void changeArray() {
synchronized(arr) {
In other words: make sure that the n threads have to lock on the same monitor; in that case the shared array.
Alternatively: instead of making changeArray() a method in that ThreadableClass ... create a class
ArrayUpdater {
int arr[] to update
synchronized changeArray() ...
Then create one instance of that class; and give that same instance to each of your threads. Now the sync'ed method will prevent multiple threads to enter!
Because you are providing new instance for each theard using new ThreadableClass(barrier, arr), basically, all the theadrs are using different ThreadableClass objects, so your code synchronized methods run parallely, so you need to use a single ThreadableClass object as shown below:
ThreadableClass threadableClass= new ThreadableClass(barrier, arr);
for (int i = 0; i < numThreads; i++) {
Thread newThread = new Thread(threadableClass);
threads.add(newThread);
}
The important point is synchronization is all about providing access (i.e., key) to an object for a single thread at a time. If you are using a different object for each thread, threads don't wait for the key because each thread has got its own key (like in your example).

JVM seems to stop context switching very quickly

I'm implementing the naive version of the Producer-Consumer concurrency problem. And it the threads are switched between at first very quickly but then stop around i = 50. Adding additional print statements for some reason allows the JVM to context switch the threads and complete the program.
Why doesn't the JVM context switch the threads so that the program will complete?
// Producer - Consumer problem
// Producer constantly puts items into array, while consumer takes them out
class IntBuffer {
private int[] buffer;
private int index;
public IntBuffer(int size) {
buffer = new int[size];
index = 0;
}
public void add(int item) {
while (true) {
if (index < buffer.length) {
buffer[index] = item;
index++;
return;
}
}
}
public int remove() {
while (true) {
if (index > 0) {
index--;
int tmp = buffer[index];
buffer[index] = 0;
return tmp;
}
}
}
public void printState() {
System.out.println("Index " + index);
System.out.println("State " + this);
}
public String toString() {
String res = "";
for (int i = 0; i < buffer.length; i++) {
res += buffer[i] + " ";
}
return res;
}
}
class Producer extends Thread {
private IntBuffer buffer;
public Producer(IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("added " + i);
buffer.add(i);
}
}
}
class Consumer extends Thread {
private IntBuffer buffer;
public Consumer(IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("removed " + i);
buffer.remove();
}
}
}
public class Main {
public static void main(String[] args) {
IntBuffer buf = new IntBuffer(10);
Thread t1 = new Thread(new Producer(buf));
Thread t2 = new Thread(new Consumer(buf));
t1.start();
t2.start();
System.out.println(buf);
}
}
Your question does not provide enough details to give an answer with a confidence(at least, it is not clear where those additional print statements go), so I'll make some(reasonable) guesses here.
Your code is not correct. IntBuffer is not thread-safe, but it is accessed from multiple threads.
Any operations on the IntBuffer do not establish a happens-before relationship, so the changes made by one thread may be not visible for another thread. That's why the Producer thread can "believe" that the buffer is full while the Consumer thread "believes" that it is empty. In this case the program never terminates.
This two statements are not guesses, they are facts based on the Java memory model. And here goes my guess why the additional print statements sorta fix it:
In many JVM implementations, the println methods uses syncronization internally. That's why a call to it creates a memory fence and makes changes made in one thread visible to the other one, eliminating the issue described in 2).
However, if you really want to solve this problem, you should make the IntBuffer thread-safe.
At the minimum you need the volatile keyword on both the buffer and index. Second, you need to access index only once under the true arm of the ifs you have there. Even after that, you will face out of bounds access at 10, you will need more fixing to work around that. Your buffer is de facto stack. So, even after all of this, your remove() can be working with stale index, thus you will be removing in the middle of the stack. You could use 0 as special value marking the slot already handled end empty.
With all of this, I do not think your code is easily salvageable. It pretty much needs complete rewrite using proper facilities. I agree with #kraskevich:
#StuartHa Naive usually means simple(and most likely inefficent) solution, not an incorrect one.

Multi threaded object creation slower then in a single thread

I have what probably is a basic question. When I create 100 million Hashtables it takes approximately 6 seconds (runtime = 6 seconds per core) on my machine if I do it on a single core. If I do this multi-threaded on 12 cores (my machine has 6 cores that allow hyperthreading) it takes around 10 seconds (runtime = 112 seconds per core).
This is the code I use:
Main
public class Tests
{
public static void main(String args[])
{
double start = System.currentTimeMillis();
int nThreads = 12;
double[] runTime = new double[nThreads];
TestsThread[] threads = new TestsThread[nThreads];
int totalJob = 100000000;
int jobsize = totalJob/nThreads;
for(int i = 0; i < threads.length; i++)
{
threads[i] = new TestsThread(jobsize,runTime, i);
threads[i].start();
}
waitThreads(threads);
for(int i = 0; i < runTime.length; i++)
{
System.out.println("Runtime thread:" + i + " = " + (runTime[i]/1000000) + "ms");
}
double end = System.currentTimeMillis();
System.out.println("Total runtime = " + (end-start) + " ms");
}
private static void waitThreads(TestsThread[] threads)
{
for(int i = 0; i < threads.length; i++)
{
while(threads[i].finished == false)//keep waiting untill the thread is done
{
//System.out.println("waiting on thread:" + i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Thread
import java.util.HashMap;
import java.util.Map;
public class TestsThread extends Thread
{
int jobSize = 0;
double[] runTime;
boolean finished;
int threadNumber;
TestsThread(int job, double[] runTime, int threadNumber)
{
this.finished = false;
this.jobSize = job;
this.runTime = runTime;
this.threadNumber = threadNumber;
}
public void run()
{
double start = System.nanoTime();
for(int l = 0; l < jobSize ; l++)
{
double[] test = new double[65];
}
double end = System.nanoTime();
double difference = end-start;
runTime[threadNumber] += difference;
this.finished = true;
}
}
I do not understand why creating the object simultaneously in multiple threads takes longer per thread then doing it in serial in only 1 thread. If I remove the line where I create the Hashtable this problem disappears. If anyone could help me with this I would be greatly thankful.
Update: This problem has an associated bug report and has been fixed with Java 1.7u40. And it was never an issue for Java 1.8 as Java 8 has an entirely different hash table algorithm.
Since you are not using the created objects that operation will get optimized away. So you’re only measuring the overhead of creating threads. This is surely the more overhead the more threads you start.
I have to correct my answer regarding a detail, I didn’t know yet: there is something special with the classes Hashtable and HashMap. They both invoke sun.misc.Hashing.randomHashSeed(this) in the constructor. In other words, their instances escape during construction which has an impact on the memory visibility. This implies that their construction, unlike let’s say for an ArrayList, cannot optimized away, and multi-threaded construction slows down due to what happens inside that method (i.e. synchronization).
As said, that’s special to these classes and of course this implementation (my setup:1.7.0_13). For ordinary classes the construction time goes straight to zero for such code.
Here I add a more sophisticated benchmark code. Watch the difference between DO_HASH_MAP = true and DO_HASH_MAP = false (when false it will create an ArrayList instead which has no such special behavior).
import java.util.*;
import java.util.concurrent.*;
public class AllocBench {
static final int NUM_THREADS = 1;
static final int NUM_OBJECTS = 100000000 / NUM_THREADS;
static final boolean DO_HASH_MAP = true;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
Callable<Long> task=new Callable<Long>() {
public Long call() {
return doAllocation(NUM_OBJECTS);
}
};
long startTime=System.nanoTime(), cpuTime=0;
for(Future<Long> f: threadPool.invokeAll(Collections.nCopies(NUM_THREADS, task))) {
cpuTime+=f.get();
}
long time=System.nanoTime()-startTime;
System.out.println("Number of threads: "+NUM_THREADS);
System.out.printf("entire allocation required %.03f s%n", time*1e-9);
System.out.printf("time x numThreads %.03f s%n", time*1e-9*NUM_THREADS);
System.out.printf("real accumulated cpu time %.03f s%n", cpuTime*1e-9);
threadPool.shutdown();
}
static long doAllocation(int numObjects) {
long t0=System.nanoTime();
for(int i=0; i<numObjects; i++)
if(DO_HASH_MAP) new HashMap<Object, Object>(); else new ArrayList<Object>();
return System.nanoTime()-t0;
}
}
What about if you do it on 6 cores? Hyperthreading isn't the exact same as having double the cores, so you might want to try the amount of real cores too.
Also the OS won't necessarily schedule each of your threads to their own cores.
Since all you are doing is measuring the time and churning memory, your bottleneck is likely to be in your L3 cache or bus to main memory. In this cases, coordinating the work between threads could be producing so much overhead it is worse instead of better.
This is too long for a comment but your inner loop can be just
double start = System.nanoTime();
for(int l = 0; l < jobSize ; l++){
Map<String,Integer> test = new HashMap<String,Integer>();
}
// runtime is an AtomicLong for thread safety
runtime.addAndGet(System.nanoTime() - start); // time in nano-seconds.
Taking the time can be as slow creating a HashMap so you might not be measuring what you think you if you call the timer too often.
BTW Hashtable is synchronized and you might find using HashMap is faster, and possibly more scalable.

how do I set up the following thread in Java?

I have a thread with the following form:
each execution of each thread is supposed to run a function in the class. That function is completely safe to run by itself. The function returns a value, say an int.
After all threads have been executed, the function values need to be accumulated.
So, it goes (in pseudo-code) something like that:
a = 0
for each i between 1 to N
spawn a thread independently and call the command v = f(i)
when thread finishes, do safely: a = a + v
end
I am not sure how to use Java in that case.
The problem is not creating the thread, I know this can be done using
new Thread() {
public void run() {
...
}
}
the problem is accumulating all the answers.
Thanks for any info.
I would probably do something like:
public class Main {
int a = 0;
int[] values;
int[] results;
public Main() {
// Init values array
results = new int[N];
}
public int doStuff() {
LinkedList<Thread> threads = new LinkedList<Thread>();
for (final int i : values) {
Thread t = new Thread() {
public void run() {
accumulate(foo(i));
}
};
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
// Act accordingly, maybe ignore?
}
}
return a;
}
synchronized void accumulate(int v) {
// Synchronized because a += v is actually
// tmp = a + v;
// a = tmp;
// which can cause a race condition AFAIK
a += v;
}
}
Use an ExecutorCompletionService, Executor, and Callable.:
Start with a Callable that calls your int function:
public class MyCallable implements Callable<Integer> {
private final int i;
public MyCallable(int i) {
this.i = i;
}
public Integer call() {
return Integer.valueOf(myFunction(i));
}
}
Create an Executor:
private final Executor executor = Executors.newFixedThreadPool(10);
10 is the maximum number of threads to execute at once.
Then wrap it in an ExecutorCompletionService and submit your jobs:
CompletionService<Integer> compService = new ExecutionCompletionService<Integer>(executor);
// Make sure to track the number of jobs you submit
int jobCount;
for (int i = 0; i < n; i++) {
compService.submit(new MyCallable(i));
jobCount++;
}
// Get the results
int a = 0;
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
}
ExecutorCompletionService allows you to pull tasks off of a queue as they complete. This is a little different from joining threads. Although the overall outcome is the same, if you want to update a UI as the threads complete, you won't know what order the threads are going to complete using a join. That last for loop could be like this:
for (int i = 0; i < jobCount; i++) {
a += compService.take().get().intValue();
updateUi(a);
}
And this will update the UI as tasks complete. Using a Thread.join won't necessarily do this since you'll be getting the results in the order that you call the joins, not the order that the threads complete.
Through the use of the executor, this will also allow you to limit the number of simultaneous jobs you're running at a given time so you don't accidentally thread-bomb your system.

Multithreaded code in Java with ExecutorService fails to return, why?

I have very similar multithreaded code elsewhere in my codebase that works fine, but I can't see quite what's going wrong here.
This is a simple multi-threaded process to generate some result XML for a search query. The output of running this method is:
Returning from threads
The line System.out.println("Finished multithreading loop");" is never reached.
Modifying the number of threads doesn't help.
private void fillAllResults() {
int threads = 2;
final FutureTask[] tasks = new FutureTask[threads];
final ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < allResults.size(); i++) {
tasks[i] = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
int index;
while ((index = getResultsIndex()) < allResults.size()) {
System.out.println("Processing result " + index);
Result result = allResults.get(index);
fillResultXML(result);
}
System.out.println("Returning from threads");
return 1;
}
});
executor.execute(tasks[i]);
}
for (int i = 0; i < threads; i++) {
try {
tasks[i].get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executor.shutdown();
System.out.println("Finished multithreading loop");
}
Edit, thanks all for the quick replies! Here's the answers:
It shows 'processing result' as many times as I have results. If allResults.size() is 25, it shows processing result 1, processing result 2 ... processing result 24.
Here's the extra code that's missing:
private List<Result> allResults = new ArrayList<Result>();
private int resultsIndex = 0;
private synchronized int getResultsIndex() {
return resultsIndex++;
}
And in case anyone's wondering, I can guarantee that none of the code within the loop increases the size of allResults.
I suppose it is related to the fact, that your array tasks has a length of threads (i.e. two in your case) but you assign more values to it within the lines
for (int i = 0; i < allResults.size(); i++) {
tasks[i] = ...
....
}
If your list allResults has more than two entries your thread will be stopped by an ArrayIndexOutOfBoundsException. Maybe you catch this one but do not handle it properly outside the code you presented.
It looks like getResultsIndex() isn't updating after every loop resulting in an infinite loop.
It's not clear from your code what allResults and getResultsIndex are, but you never seem to update whatever getResultsIndex returns.

Categories

Resources