|
| 1 | +package com.codinko.threads; |
| 2 | + |
| 3 | +/** |
| 4 | + * Reference: |
| 5 | + * http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html |
| 6 | + * |
| 7 | + * The most common kind of liveness problem : deadlock |
| 8 | + * |
| 9 | + * DeadLock: |
| 10 | + * |
| 11 | + * Deadlock describes a situation where two or more threads are blocked forever, |
| 12 | + * waiting for each other. Here's an example. |
| 13 | + * |
| 14 | + * Say if there are two threads A and B , and each thread require access to say |
| 15 | + * two shared resources to achieve a particular task. If thread A acquired |
| 16 | + * resource1 and is about to access resource2 so that it can complete its task. |
| 17 | + * Now, threadB acquired resource2 and is about to access resource1 so that it |
| 18 | + * can complete its task. If both of these threads decide to wait until what |
| 19 | + * they need is no longer in use [or released by the other one], then they will |
| 20 | + * wait for each other forever. That's DeadLock. |
| 21 | + * |
| 22 | + * Another example: |
| 23 | + * |
| 24 | + * One Person say "hi". The second person has to say "bye". Then only, the first |
| 25 | + * person will be able to complete his task. |
| 26 | + * |
| 27 | + * John says "hi" to Peter [John is locked]. John will be able to complete his |
| 28 | + * task only if Peter say "bye". [Peter cannot say "bye" as it already said |
| 29 | + * "hi", and can release lock on Peter object only if John say "bye"] |
| 30 | + * |
| 31 | + * Peter say "hi" to John [Peter is locked]. Peter will be able to complete his |
| 32 | + * task only if John say "bye". [Similarly John cannot say "bye" as it already |
| 33 | + * said "hi", and can release lock on John object only if Peter say "bye"]. |
| 34 | + * |
| 35 | + * Both of them does not complete their task, waiting for each other. DeadLock. |
| 36 | + * |
| 37 | + */ |
| 38 | +public class _10DeadLock { |
| 39 | + static class Friend { |
| 40 | + private final String name; |
| 41 | + |
| 42 | + public Friend(String name) { |
| 43 | + this.name = name; |
| 44 | + } |
| 45 | + |
| 46 | + public String getName() { |
| 47 | + return this.name; |
| 48 | + } |
| 49 | + |
| 50 | + // recipient - the person who greets |
| 51 | + public synchronized void sayHi(Friend recipient) { |
| 52 | + System.out.format("%s" + " said hi to %s %n", this.name, |
| 53 | + recipient.getName()); |
| 54 | + /* |
| 55 | + * Let's say this is john.sayHi(peter);. "hi" is told by Peter. Now |
| 56 | + * John have to say "bye" to Peter. invoke sayBye() on this |
| 57 | + * recipient object[ both the objects hold lock at this point of |
| 58 | + * Time Hence indefinitely waits!! for other thread to release |
| 59 | + * lock!!] |
| 60 | + */ |
| 61 | + recipient.sayBye(this); |
| 62 | + /* |
| 63 | + * if recipient object is locked by a different thread, this current |
| 64 | + * thread cannot complete! |
| 65 | + */ |
| 66 | + } |
| 67 | + |
| 68 | + public synchronized void sayBye(Friend recipient) { |
| 69 | + System.out.format("%s" + " said bye to %s %n", this.name, |
| 70 | + recipient.getName()); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + public static void main(String[] args) { |
| 75 | + final Friend john = new Friend("John"); |
| 76 | + final Friend peter = new Friend("Peter"); |
| 77 | + |
| 78 | + new Thread(new Runnable() { |
| 79 | + public void run() { |
| 80 | + john.sayHi(peter); /* |
| 81 | + * this thread has put a lock on john object |
| 82 | + * on encountering synchronized 'sayHi()' |
| 83 | + */ |
| 84 | + |
| 85 | + } |
| 86 | + }, "thread1").start(); |
| 87 | + new Thread(new Runnable() { |
| 88 | + public void run() { |
| 89 | + peter.sayHi(john); /* |
| 90 | + * this thread has put a lock on peter |
| 91 | + * object on encountering synchronized |
| 92 | + * 'sayHi()' |
| 93 | + */ |
| 94 | + } |
| 95 | + }, "thread2").start(); |
| 96 | + } |
| 97 | +} |
0 commit comments