https://www.gravatar.com/avatar/306d401b2a8c0efe0996fec60e0c90aa?s=240&d=mp

My coding journey

Disclaimer: it's just for fun

Modern Java in Action 3 - collection API

New API (in Java 8)

Collection classes got a few nice additions.

Factory methods

They create immutable collection (if you try to add/remove elements, you get UnsupportedOperationException. There is no varargs variant - this variant would require additional array allocation, which non-varargs variants don’t have.

There are overloads from 1 to 10 elements.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//static <E> List<E> of(E... elements)

static <E> List<E> of(E e1)
static <E> List<E> of(E e1, E e2)
static <E> List<E> of(E e1, E e2, E e3)
static <E> List<E> of(E e1, E e2, E e3, E e4)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5)
// ... other variants


static <E> Set<E> of(E e1)
static <E> Set<E> of(E e1, E e2)
//... etc, other variants up to 10 


static <K, V> Map<E> of(K k1, V v1)
static <K, V> Map<E> of(K k1, V v1, K k2, V v2)
// ... etc, variants up to 10 pairs
// or with entries
import static java.util.Map.entry;
static <K, V> Map<E> ofEntries(entry(k1, v1), entry(k2, v2))

lists: removeIf, replaceAll

On a list you can use removeIf and replaceAll

Modern Java in Action 2 - fork-join and spliterators

Second chapter shows how parallellization works with streams; explains what fork-join pool is (which is used by streams framework underneath), what data structures are decomposable, how to create your own spliterator for more effective splitting of source stream for parallel processing.

Parallel streams

  • created by a call to parallel() in a chain of stream operations
  • fork/join pool uses Runtime.getRuntime().available-Processors() number of threads by default, but you can change it by specifying java.util.concurrent.ForkJoinPool.common.parallelism system property:
    1
    
    System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "12");
    

Hints

  • measure (check Java Microbenchmark Harness (JMH))
  • beware boxing/unboxing operations (use IntStream, DoubleStream of FloatStream)
  • limit() and findFirst() are worse on parallel streams (they require order) than findAny() with unordered()
  • don’t use inherently sequential functions: instead of this one, which is not easily parallelisable:
    1
    
    Stream.iterate(1L, i -> i + 1).limit(N)
    
    you should rather use:
    1
    
    LongStream.rangeClosed(1, N)
    
    which works on long values (no boxing) and produces easliy splittable range ideal for parallelization.
  • know which data structures are easily decomposable (ArrayList is - it can be split without traversing it, LinkedList isn’t)
  • performance depends also on order of stream operations which may change stream characteristics (SIZED stream can be split, filtered stream has unknow number of elems)
  • note the cost of terminal operation (if high - parallel time gain can be smaller that time used for combining partial results)

Decomposability table

class composability
ArrayList 😄 Excellent
IntStream.range 😄 Excellent
HashSet 😐 Good
TreeSet 😐 God
LinkedList 😭 Bad
Stream.iterate 😭 Bad

Fork Join pool

  • ForkJoinPool is an implementation of ExecutorService
  • requires creation of a RecursiveTask subclass with protected abstract R compute();
  • to use it, use following algorithm:
1
2
3
4
5
6
7
8
if (task is small enough or no longer divisible) {
    compute task sequentially
} else {
    split task in two subtasks
    call this method recursively possibly further splitting each subtask
    wait for the completion of all subtasks
    combine the results of each subtask
}
  • remember: join() is blocking, so use it after results of subtasks are ready
  • as a RecursiveTask, use compute() and fork(), don’t use the invoke() on a pool
  • wisely decide the criteria if the task should be split further (see example in a javadoc for RecursiveAction class where getSurplusQueuedTaskCount() is used for the criteria)
  • subtasks should take longer than creation of a new task
  • it is hard to debug (as with all multithreaded programs)
  • it is hard to measure, due to the fact that fork-join should be warmed-up

Work stealing

  • goal: ensure even distribution of work between threads
  • each thread in the pool keeps doubly-linked list of tasks to execute, takes one by one from the head and executes
  • if no more tasks it thread’s onw queue, it randomly selects a thread with no-empty queue and steals a task from the tail of that queue

Important You don’t have to use fork-join if your datastructure is decomposable; you just use parallel data streams. Automatic way of traversing a source and splitting it is “spliterator” - the interface which standard collections implement in the default implementation.

Encrypted Directory With encfs

I would like to keep my secrets in encrypted directory. It seems that there already exists a nice solution to this problem and it is called encfs.

For reference, I found online manual with examples after visiting baeldung linux article first.

So, let’s do it.

Create a pair of directories

Here I’m creating two directories:

  • ~/.crypt is the source directory - here encrypted data are stored
  • ~/crypt directory which is the mountpoint - here I would see decrypted files to work with
1
[karma@tpd] mkdir ~/crypt ~/.crypt

Create encfs

Now, in order to start working with encsfs I issue following command: encfs source mountpoint:

JavaScript Canvas Easter Eggs

It’s snowy and rainy, although it is April already according to the calendar. A few days ago I’ve seen little yellow flowers growing in the snow (snowdrops and aconite). It’s also very windy today (I can hear howling in ventilation chimneys) and it was raining all night long.

I need some more colors to dissipate the unpeasant aura. I’ve decided to write a small graphics generator for easter eggs.

The code is available at GitLab, in snowflake project and the generator itself is available on kamilachyla.gitlab.io page.

JVM: Loading, Linking, Initializing

This chapter of JVM Specification describes three phases of life of a JVM class: loading, linking and initializing.

Good read
A good read from the perspective of a Java programmer is chapter 12 of Java Language Specification which describes the execution of Java program starting from a main method of the starting class (also called: main class).

In order to start executing main method (public void main(String[] args)) of the main (or: initial) class the JVM needs to have a runtime representation of the class. If JVM does not have it, it needs to construct it from binary representation. This is called loading.

JVM: Verification and Checks

The weather is still “very february”, so I grab a cup coffee ☕, start reading and taking notes.

This post completes Chapter 4 of the JVM Specification - it quickly goes through format checking, shows two types of Code attribute checks and lists JVM limitations.

Format Checking

Before the class is loaded, JVM needs to ensure that the .class file has appropriate format. There are five basic integrity checks that are performed on a .class file:

JVM: Fields, Methods, Attributes

Attributes in the .class file layout

In previous post I made some notes about constant_pool. Looking at the order in which data is layed out in the class file, constant_pool is followed by some general information specific to the class like its name, names of implemented interfaces or its superclass (see the post JVM: Class file structure). Information about fields and methods comes next.

Both fields as well as methods are represented with the same general structure: