2015年8月29日 星期六

Java 並行 API

Java 的 java.util.concurrent.atomic 應用:
import java.util.concurrent.atomic.*;

public class Demo{

 public static void main(String[] args){
  
  AtomicInteger ai = new AtomicInteger(5);
  
  if (ai.compareAndSet(5,42)){
   System.out.println("The current value: " + ai.get());
   System.out.println("Replaced 5 with 42");
  }
 }
}

Concurrent I/O 的應用:
public class MultiThreadedClientMain {
    public static void main(String[] args){
        ExecutorService es = Executors.newCachedThreadPool();
        Map < RequestResponse,Future < RequestResponse >> callables = 
                                                     new HashMap<>();
        
        String host = "localhost";
        for (int port = 10000; port <  10010 ; port++){
            RequestResponse lookup = new RequestResponse(host, port);
            NetworkClientCallable callable = 
                                  new NetworkClientCallable(lookup);
            Future future = es.submit(callable);
            callables.put(lookup, future);
        }
        es.shutdown();
        try{
            es.awaitTermination(5, TimeUnit.SECONDS);
        } catch(InterruptedException ex){
            System.out.println("Stopped waiting early");
        }
        
        for (RequestResponse lookup : callables.keySet()){
            Future future = callables.get(lookup);
            try {
                lookup = future.get();
                System.out.println(lookup.host + ":" + lookup.port + 
                     " " + lookup.response);
            } catch (ExecutionException | InterruptedException ex){
                System.out.println("Error talking to " + lookup.host +
                        ":" + lookup.port);
            }
        }
    }
}

public class RequestResponse {
    public String host;
    public int port;
    public String response;
    
    public RequestResponse(String host, int port){
        this.host = host;
        this.port = port;
    }
}

public class NetworkClientCallable implements Callable < RequestResponse > {
    private RequestResponse lookup;
    
    public NetworkClientCallable(RequestResponse lookup) {
        this.lookup = lookup;
    }

    @Override
    public RequestResponse call() throws IOException {
        try (Socket sock = new Socket(lookup.host, lookup.port);
             Scanner scanner = new Scanner(sock.getInputStream());){
            lookup.response = scanner.next();
        }
        return lookup;
    }   
}