Why does Living instanceof Player in non-server thread block the thread?


#1

Hello,
I’m currently porting my plugin to Sponge and it’s going great

I ran into some interesting behavior and would like to know why it occurs.

Code:
There is an ExecutorService:

 criticalExecutor = Executors.newFixedThreadPool(2);

I have a Listener that listens for DestructEntityEvent.Death, gets the dead entity as well as the killer of that entity.

@Listener
public void onEntityDeath(DestructEntityEvent.Death event) {
    Living dead = event.getTargetEntity();
    ...
    criticalExecutor.submit(new KillRunnable(dead))
}

The runnable then Freezes when run.

@Override
public void run() {
    System.out.println("*");
    if (dead instanceof Player) {
        System.out.println("Dead player");
    } else {
        System.out.println("Dead mob");
    }
    System.out.println("**");
}

Prints out:

[19:01:10 INFO] [STDOUT]: *

I know that I can place the check inside the Listener (And I will), but I’m interested in what causes the blocking behavior.


#2

Personally, I don’t know whether it’s because the thread is not closing, but also, making new threads and then submitting them can still block the main thread if you’re not using something like the API scheduler (which overall does thread management for you).

Have you tried using Tasks?


#3

Main thread is not being blocked by this, but the thread that calls the runnable outside of the main thread.

I dunno the technique used to block here. (I’m trying to learn Java concurrency in another project, which is why I’m interested.)

I mean I could use the sponge tasks for every kill, but I think it adds overhead when in the end it’s likely Sponge is using something similar to ExcecutorServices to manage the tasks.

As for the check itself, executing the check in the event listener method did not block, so that’s all done and good. :slight_smile:


#4

Well i don’t see any code in your runnable that should block.

With my limited knowledge of java, there should be absolutely no way for a java thread to just stop mid execution like that without something dumb like Thread.kill() or some seriously aggressive OS prioritization.

Or a breakpoint, so make sure you didn’t set any.

Also make sure that the asterisk is ACTUALLY being printed by your runnable and not by something else, cause it’s more likely that your runnable isn’t actually being scheduled to run at all.


#5

This code works for me: http://prntscr.com/j40b2y

My guess is that as @gravityfox said, you probably have a breakpoint or something else (a profiler or something maybe) that is grabbing and hanging it.

I am assuming that you don’t have any special JVM arguments you are using.


#6

After trying it again today the code no longer blocked.

Might have been some sort of a hiccup with the JVM or compiler error or something else entirely ¯\_(ツ)_/¯