Back Home

Async Java

Libraries

Multi Threaded

Executors

The Concurrency API introduces the concept of an ExecutorService as a higher level replacement for working with threads directly. Executors are capable of running asynchronous tasks and typically manage a pool of threads, so we don't have to create new threads manually. All threads of the internal pool will be reused under the hood for revenant tasks, so we can run as many concurrent tasks as we want throughout the life-cycle of our application with a single executor service.

This is how the first thread-example looks like using executors:

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
    String threadName = Thread.currentThread().getName();
    System.out.println("Hello " + threadName);
});

// => Hello pool-1-thread-1

A more traditional (non lamda) implemenation

ExecutorService executor = Executors.newFixedThreadPool(20);
		int i = 1;
		12.times {
			println "int worker $i"
			//new AmqWorker(i, session, producer, content, timeToRun);
			Runnable worker = new AmqWorker(i, pref_queue, content, timeToRun);
			executor.execute(worker);
			i++;
		}
		executor.shutdown

Callables and Futures

In addition to Runnable executors support another kind of task named Callable. Callables are functional interfaces just like runnables but instead of being void they return a value.

This lambda expression defines a callable returning an integer after sleeping for one second:

Callable<Integer> task = () → {

  try {
      TimeUnit.SECONDS.sleep(1);
      return 123;
  }
  catch (InterruptedException e) {
      throw new IllegalStateException("task interrupted", e);
  }

};

Callables

Runnable threads support a submit() method that doesn't return a result.

Callables can be submitted to executor services. But what about the callables result? Since submit() doesn't wait until the task completes, the executor service cannot return the result of the callable directly. Instead the executor returns a special result of type Future which can be used to retrieve the actual result at a later point in time.

ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(task);

System.out.println("future done? " + future.isDone());

Integer result = future.get();

System.out.println("future done? " + future.isDone());
System.out.print("result: " + result);

After submitting the callable to the executor we first check if the future has already been finished execution via isDone(). I'm pretty sure this isn't the case since the above callable sleeps for one second before returning the integer.

Calling the method get() blocks the current thread and waits until the callable completes before returning the actual result 123. Now the future is finally done and we see the following result on the console:

future done? false
future done? true
result: 123

Futures are tightly coupled to the underlying executor service. Keep in mind that every non-terminated future will throw exceptions if you shutdown the executor:

executor.shutdownNow();
future.get();

You might have noticed that the creation of the executor slightly differs from the previous example. We use newFixedThreadPool(1) to create an executor service backed by a thread-pool of size one. This is equivalent to newSingleThreadExecutor() but we could later increase the pool size by simply passing a value larger than one.

See also

Java Json with Jackson

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
 
import org.codehaus.jackson.map.ObjectMapper;
 
public class JacksonFoo {
	public static void main(String[] args) throws Exception {
		ObjectMapper mapper = new ObjectMapper();
 
		Map<String, Object> data = new HashMap<String, Object>();
		String []  a = {"stb1, campang3"};
		String []  b = {"stb1, campang3"};
		ArrayList arr = new ArrayList();
		arr.add(a);
		arr.add(b);
 
		data.put("aaData", arr);		
		OutputStream out = System.out;
		mapper.writeValue(out , data);
 
	}
}

will produce

{"aaData":[["stb1, campang3"],["stb1, campang3"]]}
 
java.txt · Last modified: 2016/11/15 07:00 by root
 
RSS - 200 © CrosswireDigitialMedia Ltd