Overview
-
Background: I start a thread [call thread A below]in Spark driver to handle opening files in codis, in which I start six thread [call sub threads below]to handle the files in parallel.
-
What happened:
-
I found the codis openingFilePool never update since a given time.
-
So I looked into the
Thread Dump
tools of spark, and saw that thread A is always been WAITING. As below: -
The normal one is as follow:
- See the difference?
The thread should be TIMED_WAITING(sleep), not be WAITING(wait for some other threads to awake it)! -
It seems there is a deadlock?
-
-
Thread A get a jedis instance from JedisResourcePool to get all opening files.
-
Then, the sub threads handle these opening files and interact with codis in pipeline. [I use try(Pipeline pipeline = CodisPool.getPool().getResource().pipelined())]
Possible causes
- I am not sure this is because 1) there is no enough instance in JedisPool; or 2) there is a deadlock?
-
try (Pipeline pipeline = CodisPool.getPool().getResource().pipelined())
-
I am not sure whether this code will close jedis and pipeline, or it will just close pipeline?
-
-
JedisResourcePool is not thread-safe?
-
Some says that we should sync when we getResource() from JedisResourcePool. I am not sure.
-
And also I think should I configure the number of Jedis pool.
-
-
Final words
- I have been wondering how to check whether the chained resource is closed. Uh... So I raised a question in stackoverflow.
- Show the amzaing answer:
-
Try-with-resources close only variable, in your case
Pipeline pipeline
. You can read more in docs https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.htmlYou can check it with example:
MyResource
class:class MyResource implements AutoCloseable { public SubResource getSubResource() { return new SubResource(); } @Override public void close() throws Exception { System.out.println("Resource closed"); } }
SubResource
class:class SubResource implements AutoCloseable{ @Override public void close() throws Exception { System.out.println("SubResource closed"); } }
Main
class:class Main { public static void main(String[] args) { try (SubResource s = new MyResource().getSubResource()) { System.out.println("Before closing"); } catch (Exception e) { e.printStackTrace(); } System.out.println("After closing"); } }
Execution result:
Before closing SubResource closed After closing