1) You could use rs.finish() to make sure you wait for the kernel to finish. Kernel execution is indeed asynchronous in RS.
2) We only allow one kernel to execute at a time (ignoring ScriptGroup, where you have a DAG of kernels, and thus maybe some additional room for optimizations). In this case, your second kernel won't start running until the first kernel completes.
3) Invokable functions (i.e. things you run with invoke_*() from Java) are not asynchronous. You will block until they complete on the Java side. Thus, they will block each other, or kernels. If you have a kernel followed by an invoke, you will asynchronously start the kernel, but the invoke won't begin until the kernel finishes. You will then be waiting for the invoke to finish as well.
One more detail. If your initializer doesn't require parameters, you can put it in an actual "void init(void)" function. Those get run once when the ScriptC is created.