zoukankan      html  css  js  c++  java
  • What is livelock?

    http://docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

    Livelock

    A thread often acts in response to the action of another thread. If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They're still blocking each other, so...

    后来看了看Wikipedia,上面也是讲得这个two people attempting to pass each other in a narrow corridor...

    再去stackoverflow找,有一个提问的人也表示:能不能给个具体例子?链接如下

    http://stackoverflow.com/questions/1036364/good-example-of-livelock

    下面是个例子:

    Here's a very simple Java example of livelock where a husband and wife are trying to eat soup, but only have one spoon between them. Each spouse is too polite, and will pass the spoon if the other has not yet eaten.

     1  public class Livelock 
     2  {
     3      static class Spoon
     4      {
     5          private Diner owner;
     6          public Spoon(Diner d) { owner = d; }
     7          public Diner getOwner() { return owner; }
     8          public synchronized void setOwner(Diner d) { owner = d; }
     9          public synchronized void use() { System.out.printf("%s has eaten!", owner.name); }
    10      }
    11  
    12      static class Diner
    13      {
    14          private String name;
    15          private boolean isHungry;
    16  
    17          public Diner(String n) { name = n; isHungry = true; }       
    18          public String getName() { return name; }
    19          public boolean isHungry() { return isHungry; }
    20  
    21          public void eatWith(Spoon spoon, Diner spouse) 
    22          {
    23              while (isHungry)
    24              {
    25                  // Don't have the spoon, so wait patiently for spouse.
    26                  if (spoon.owner != this)
    27                  {
    28                      try { Thread.sleep(1); } catch(InterruptedException e) { continue; }
    29                      continue;
    30                  }                       
    31  
    32                  // If spouse is hungry, insist upon passing the spoon.
    33                  if (spouse.isHungry()) 
    34                  {                   
    35                      System.out.printf("%s: You eat first my darling %s!%n", name, spouse.getName());
    36                      spoon.setOwner(spouse);
    37                      continue;
    38                  }
    39  
    40                  // Spouse wasn't hungry, so finally eat
    41                  spoon.use();
    42                  isHungry = false;               
    43                  System.out.printf("%s: I am stuffed, my darling %s!%n", name, spouse.getName());                
    44                  spoon.setOwner(spouse);
    45              }
    46          }
    47      }
    48  
    49      public static void main(String[] args) 
    50      {
    51          final Diner husband = new Diner("Bob");
    52          final Diner wife = new Diner("Alice");
    53  
    54          final Spoon s = new Spoon(husband);
    55  
    56          new Thread(new Runnable() { public void run() { husband.eatWith(s, wife); } }).start();
    57          new Thread(new Runnable() { public void run() { wife.eatWith(s, husband); } }).start();
    58      }
    59  }

    我把上面的例子改写了一下:

     1 package simple;
     2 
     3 class Spoon {
     4     private Diner owner;
     5     public Spoon(Diner diner) {
     6         owner = diner;
     7     }
     8     public Diner getOwner() {
     9         return owner;
    10     }
    11     public synchronized void setOwner(Diner diner) {
    12         owner = diner;
    13     }
    14     public synchronized void use() {
    15         System.out.printf("%s eating soup!", owner.getName());
    16     }
    17 }
    18 
    19 class Diner {
    20     private String name;
    21     private Spoon spoon;
    22     private boolean isHungry;
    23     public boolean isHungry() {
    24         return isHungry;
    25     }
    26     public String getName() {
    27         return name;
    28     }
    29     public Diner(String name) {
    30         this.name = name;
    31         isHungry = true;
    32     }
    33     public void eatWith(Spoon spoon, Diner another) throws InterruptedException {
    34         synchronized (spoon) {
    35             // don't have the spoon, so wait patiently for another:
    36             while (spoon.getOwner() != this) {
    37                 spoon.wait();
    38             }
    39             // get the spoon, if 'another' is hungry, insist upon passing the spoon...
    40             while (another.isHungry()) {
    41                 //! Here is what makes livelock happen:
    42                 spoon.setOwner(another);
    43                 System.out.println(name + ": you eat first, " + another.getName());
    44                 spoon.notifyAll();
    45                 spoon.wait();
    46             }
    47         }
    48         // 'another' wasn't hungry, so finally eat:
    49         spoon.use();
    50         isHungry = false;
    51         System.out.println(name + ": I'm stuffed");
    52         spoon.setOwner(another);
    53     }
    54 }
    55 
    56 public class Foo {
    57     public static void main(String[] args) throws Exception {
    58         final Diner wife = new Diner("Amy");
    59         final Diner husband = new Diner("Bob");
    60         final Spoon spoon = new Spoon(wife);
    61         new Thread(new Runnable() {
    62             @Override
    63             public void run() {
    64                 try {
    65                     wife.eatWith(spoon, husband);
    66                 } catch (InterruptedException e) {
    67                     e.printStackTrace();
    68                 }
    69             }
    70         }).start();
    71         new Thread(new Runnable() {
    72             @Override
    73             public void run() {
    74                 try {
    75                     husband.eatWith(spoon, wife);
    76                 } catch (InterruptedException e) {
    77                     e.printStackTrace();
    78                 }
    79             }
    80         }).start();
    81     }
    82 }
  • 相关阅读:
    使用Orachard与Bootstrap建站心得
    【02C语言】11函数的声明和定义
    【02C语言】09流程控制
    有趣的linux命令
    杭州哪家整容医院比较有威望?
    DDD:在基于关系数据库的领域,聚合的边界等于并发管理的边界。
    TOGAF架构开发方法(ADM)之业务架构阶段
    构建一个真实的应用电子商务SportsStore(八)
    Lucene分词组件盘古与mmseg4j评测
    .NET PDB文件到底是什么?
  • 原文地址:https://www.cnblogs.com/qrlozte/p/3129282.html
Copyright © 2011-2022 走看看