Search code examples
javamultithreadingjava-threads

How to retrieve the result from the fastest between two threads


The main usage of my Android app is to fetch one URL extremely fast, and I needed to implement two ways to fetch this website:

  • 1: Via a normal request using the normal network
  • 2: Via a Proxy-Server

Due to the fact that sometimes loading the website without a proxy results in a http-error, I'd like try both ways simultaneously and go with the fastest one.

This is what I tried so far:

    final boolean[] thread1Done = {false};
    final boolean[] thread2Done = {false};

    new Thread(new Runnable() {
        @Override
        public void run() {
            website = fetchWebsiteViaProxy();
            thread1Done[0] = true;
        }
    }).start();
    
    new Thread(new Runnable() {
        @Override
        public void run() {
            website = fetchWebsiteWithoutProxy();
            thread2Done[0] = true;
        }
    }).start();


    //Wait until both threads are done and at least one has managed to fetch the website
    while (thread1Done[0] == false || thread2Done[0] == false || website.length() == 0) {
        Thread.sleep(10);
    }
    
    //... continue

The above is just pseudocode so for the sake of this example, we could assume that at least one of those threads will always manage to successfully fetch the website.

But I think there must be a better way than just to wait for the result with a while().

Thank you for your help.


Solution

  • What version of Android you need to support? Can you use CompletableFuture? If, yes you can use following pattern:

     CompletableFuture<Website> future = new CompletableFuture<>();
    
    new Thread(new Runnable() {
      @Override
      public void run() {
        website = fetchWebsiteViaProxy();        
        future.complete(website);
      }
    }).start();
    
    new Thread(new Runnable() {
      @Override
      public void run() {
        website = fetchWebsiteWithoutProxy();        
        future.complete(website);
      }
    }).start();
    
    //return the result fromt he faster thread
    Website result = future.get();