| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 62c5ec5 commit 53e397b
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,45 @@ | |||
| 1 | + Sample to a deadlock in Java Application | ||
| 2 | + =========================================== | ||
| 3 | + | ||
| 4 | + This sample application shows an example of a deadlock. Following is the definition of "deadlock" according to | ||
| 5 | + [Java Tutorial](https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html) | ||
| 6 | + | ||
| 7 | + > Deadlock describes a situation where two or more threads are blocked forever, waiting for each other. | ||
| 8 | + | ||
| 9 | + In this application, there are two threads trying to acquire two locks. | ||
| 10 | + | ||
| 11 | + ### How to run | ||
| 12 | + | ||
| 13 | + The application will throw Out of Memory error after some time when you run following command | ||
| 14 | + | ||
| 15 | + `java -Xms1g -Xmx1g -jar target/deadlock.jar` | ||
| 16 | + | ||
| 17 | + ### How to detect a deadlock | ||
| 18 | + | ||
| 19 | + Take a thread dump (using `jstack <pid>` command or `jcmd <pid> Thread.print`). | ||
| 20 | + | ||
| 21 | + The thread dump should show the Java level deadlock details as follows. | ||
| 22 | + | ||
| 23 | + ``` | ||
| 24 | + Found one Java-level deadlock: | ||
| 25 | + ============================= | ||
| 26 | + "Thread Group 1-2": | ||
| 27 | + waiting to lock monitor 0x00007f8ab4003a78 (object 0x00000000eaca1488, a java.lang.Object), | ||
| 28 | + which is held by "Thread Group 1-1" | ||
| 29 | + "Thread Group 1-1": | ||
| 30 | + waiting to lock monitor 0x00007f8ab4006518 (object 0x00000000eaca1498, a java.lang.Object), | ||
| 31 | + which is held by "Thread Group 1-2" | ||
| 32 | + | ||
| 33 | + Java stack information for the threads listed above: | ||
| 34 | + =================================================== | ||
| 35 | + "Thread Group 1-2": | ||
| 36 | + at com.github.chrishantha.sample.deadlock.DeadlockApplication$SampleLockThread.run(DeadlockApplication.java:54) | ||
| 37 | + - waiting to lock <0x00000000eaca1488> (a java.lang.Object) | ||
| 38 | + - locked <0x00000000eaca1498> (a java.lang.Object) | ||
| 39 | + "Thread Group 1-1": | ||
| 40 | + at com.github.chrishantha.sample.deadlock.DeadlockApplication$SampleLockThread.run(DeadlockApplication.java:54) | ||
| 41 | + - waiting to lock <0x00000000eaca1498> (a java.lang.Object) | ||
| 42 | + - locked <0x00000000eaca1488> (a java.lang.Object) | ||
| 43 | + | ||
| 44 | + Found 1 deadlock. | ||
| 45 | + ``` | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,47 @@ | |||
| 1 | + <?xml version="1.0" encoding="utf-8"?> | ||
| 2 | + <!-- | ||
| 3 | + # Copyright 2018 M. Isuru Tharanga Chrishantha Perera | ||
| 4 | + # | ||
| 5 | + # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + # you may not use this file except in compliance with the License. | ||
| 7 | + # You may obtain a copy of the License at | ||
| 8 | + # | ||
| 9 | + # http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + # | ||
| 11 | + # Unless required by applicable law or agreed to in writing, software | ||
| 12 | + # distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + # See the License for the specific language governing permissions and | ||
| 15 | + # limitations under the License. | ||
| 16 | + --> | ||
| 17 | + <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 18 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 19 | + | ||
| 20 | + <parent> | ||
| 21 | + <groupId>com.github.chrishantha.sample</groupId> | ||
| 22 | + <artifactId>java-samples</artifactId> | ||
| 23 | + <version>0.0.2-SNAPSHOT</version> | ||
| 24 | + <relativePath>../pom.xml</relativePath> | ||
| 25 | + </parent> | ||
| 26 | + | ||
| 27 | + <modelVersion>4.0.0</modelVersion> | ||
| 28 | + <artifactId>deadlock</artifactId> | ||
| 29 | + <packaging>jar</packaging> | ||
| 30 | + <name>deadlock</name> | ||
| 31 | + | ||
| 32 | + <dependencies> | ||
| 33 | + <dependency> | ||
| 34 | + <groupId>com.github.chrishantha.sample</groupId> | ||
| 35 | + <artifactId>base</artifactId> | ||
| 36 | + </dependency> | ||
| 37 | + </dependencies> | ||
| 38 | + | ||
| 39 | + <build> | ||
| 40 | + <plugins> | ||
| 41 | + <plugin> | ||
| 42 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 43 | + <artifactId>maven-shade-plugin</artifactId> | ||
| 44 | + </plugin> | ||
| 45 | + </plugins> | ||
| 46 | + </build> | ||
| 47 | + </project> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,90 @@ | |||
| 1 | + /* | ||
| 2 | + * Copyright 2018 M. Isuru Tharanga Chrishantha Perera | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + package com.github.chrishantha.sample.deadlock; | ||
| 17 | + | ||
| 18 | + import com.beust.jcommander.Parameter; | ||
| 19 | + import com.github.chrishantha.sample.base.SampleApplication; | ||
| 20 | + | ||
| 21 | + public class DeadlockApplication implements SampleApplication { | ||
| 22 | + | ||
| 23 | + @Parameter(names = "--count", description = "Number of deadlocks") | ||
| 24 | + private int count = 1; | ||
| 25 | + | ||
| 26 | + @Parameter(names = "--delay", description = "Delay in milliseconds to start a new thread group") | ||
| 27 | + private int delay = 0; | ||
| 28 | + | ||
| 29 | + private static class SampleLockThread extends Thread { | ||
| 30 | + | ||
| 31 | + private final Object lock1; | ||
| 32 | + private final Object lock2; | ||
| 33 | + | ||
| 34 | + public SampleLockThread(final String name, final Object lock1, final Object lock2) { | ||
| 35 | + super(name); | ||
| 36 | + this.lock1 = lock1; | ||
| 37 | + this.lock2 = lock2; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + public void run() { | ||
| 42 | + System.out.format("%s: Acquiring lock : %s%n", getName(), lock1); | ||
| 43 | + synchronized (lock1) { | ||
| 44 | + System.out.format("%s: Acquired lock : %s%n", getName(), lock1); | ||
| 45 | + try { | ||
| 46 | + Thread.sleep(100); | ||
| 47 | + } catch (InterruptedException e) { | ||
| 48 | + e.printStackTrace(); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + System.out.format("%s: Acquiring lock : %s%n", getName(), lock2); | ||
| 52 | + synchronized (lock2) { | ||
| 53 | + System.out.format("%s: Acquired lock : %s%n", getName(), lock2); | ||
| 54 | + | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + @Override | ||
| 61 | + public void start() { | ||
| 62 | + final String nameFormat = "Thread Group %2d-%d"; | ||
| 63 | + for (int i = 1; i <= count; i++) { | ||
| 64 | + final Object lock1 = new Object(); | ||
| 65 | + final Object lock2 = new Object(); | ||
| 66 | + SampleLockThread t1 = new SampleLockThread(String.format(nameFormat, i, 1), lock1, lock2); | ||
| 67 | + SampleLockThread t2 = new SampleLockThread(String.format(nameFormat, i, 2), lock2, lock1); | ||
| 68 | + t1.start(); | ||
| 69 | + t2.start(); | ||
| 70 | + if (delay > 0) { | ||
| 71 | + try { | ||
| 72 | + Thread.sleep(delay); | ||
| 73 | + } catch (InterruptedException e) { | ||
| 74 | + e.printStackTrace(); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @Override | ||
| 81 | + public String toString() { | ||
| 82 | + StringBuilder builder = new StringBuilder(); | ||
| 83 | + builder.append("DeadlockApplication [count="); | ||
| 84 | + builder.append(count); | ||
| 85 | + builder.append(", delay="); | ||
| 86 | + builder.append(delay); | ||
| 87 | + builder.append("]"); | ||
| 88 | + return builder.toString(); | ||
| 89 | + } | ||
| 90 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + com.github.chrishantha.sample.deadlock.DeadlockApplication | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,6 +49,7 @@ | |||
| 49 | 49 | <module>latencies</module> | |
| 50 | 50 | <module>allocations</module> | |
| 51 | 51 | <module>memoryleak</module> | |
| 52 | + <module>deadlock</module> | ||
| 52 | 53 | </modules> | |
| 53 | 54 | ||
| 54 | 55 | <dependencyManagement> | |
| Back | FazBrowse Home | New Git URL |
0 commit comments