Mutithreading with System.out.format and System.out.println

前端 未结 4 1408
梦毁少年i
梦毁少年i 2021-01-14 16:14

I came across this example on Oracle\'s Java Tutorial describing Deadlock in multi threading scenarios.

So in this example I made following change at line 17 and lin

相关标签:
4条回答
  • 2021-01-14 16:40

    The deadlock is not dependent on the println function at all. It's caused by the two threads trying to access each other, and locking on each other.

    The change from format to println will have introduced sufficient latency in the program to allow the threads to lock each other without colliding, i.e., deadlocking. So you haven't really fixed it; you've just added some latency that means the threads don't deadlock.

    0 讨论(0)
  • 2021-01-14 16:42

    There is no difference in whether you use System.out.print or System.out.format: they're basically doing the same thing.

    The deadlock occurs here if execution of Gaston.bow(Alphonse) is started between the start of Alphonse.bow(Gaston) and bower.bowBack(Alphonse) (or vice versa): the two threads are waiting for a monitor held by the other, and thus deadlock occurs.

    This happens inconsistently, because it depends upon a subtle timing issue, depending upon how the threads are scheduled - it is possible that Alphonse.bow and bower.backBack(Alphonse) complete before Gaston.bow is executed, so it looks like there is no deadlock.

    The classic way to fix this is to order the lock acquisition, so that the first the same lock is acquired first every time; this prevents the possibility of deadlock:

    public void bow(Friend bower) {  // Method no longer synchronized.
      int firstHash = System.identityHashCode(this);
      int secondHash = System.identityHashCode(bower);
    
      Object firstMonitor = firstHash < secondHash ? this : bower;
      Object secondMonitor = firstHash < secondHash ? bower : this;
      synchronized (firstMonitor) {
        synchronized (secondMonitor) {
          // Code free (*) of deadlocks, with respect to this and bower at least.
        }
      }
    }
    

    (*) It's not quite guaranteed to be deadlock free, since System.identityHashCode can return the same value for distinct objects; but that's reasonably unlikely.

    It's an application of the Birthday paradox: if you've got just two monitors, the chance of collision is something like 10^-18; but if you've got >77k monitors, a collision is more likely than not.

    0 讨论(0)
  • 2021-01-14 16:42

    You are mixing up things here.

    The fact that a piece of code can lead into a deadlock situation doesn't necessarily mean that you receive a deadlock each and any time that code runs.

    That is one of the aspects that makes multi-threading such a hard topic: if you run your code once, or 10 times, or a 100 times, and everything "works"; it is still possible that it will fail the next time.

    In other words: try putting that code in a loop on the outermost level, and sooner or later (probably sooner; if you don't do much "sleeping") you should hit the deadlock!

    If things were that easy and deadlocks could be detected that easily, we wouldn't need all those books and libraries and ideas how to deal with multi-threading ...

    0 讨论(0)
  • 2021-01-14 16:45

    To support the rest of the answers here with some actual proof I ran your code in a loop and it deadlocked 82 times out of 100 tries, so your code most definitely still deadlocks.

    0 讨论(0)
提交回复
热议问题