美文网首页
6.饥饿和公平

6.饥饿和公平

作者: 进击的勇士 | 来源:发表于2017-03-28 18:04 被阅读0次

饥饿

如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。

导致饥饿的原因

  • 高优先级线程吞噬所有的低优先级线程的CPU时间
  • 线程被永久堵塞在一个等待进入同步块的状态
  • 线程在等待一个本身也处于永久等待完成的对象(比如调用这个对象的wait方法)

实现Java的公平性

  • 使用Locks取代Synchronized块
public class Synchronizer{
  Lock lock = new Lock();

  public void doSynchronized() throws InterruptedException{
    this.lock.lock();
      //critical section, do a lot of work which takes a long time
    this.lock.unlock();
  }
}

public class Lock{
  private boolean isLocked = false;
  private Thread  lockingThread = null;

  public synchronized void lock() throws InterruptedException{
    while(isLocked){
      wait();
    }
    isLocked = true;
    lockingThread = Thread.currentThread();
  }

  public synchronized void unlock(){
    if(this.lockingThread != Thread.currentThread()){
      throw new IllegalMonitorStateException(
        "Calling thread has not locked this lock");
    }
    isLocked = false;
    lockingThread = null;
    notify();
  }
}

这个版本的lock方法和synchronized就公平性而言,没有任何区别

  • 使用公平锁
public class FairLock {
    private boolean isLocked = false;
    private Thread lockingThread  = null;
    private List<QueueObject> waitingThreads =
            new ArrayList<QueueObject>();

    public void lock() throws InterruptedException{
        QueueObject queueObject = new QueueObject();
        boolean isLockedForThisThread = true;
        synchronized(this){
            waitingThreads.add(queueObject);
        }

        while(isLockedForThisThread){
          synchronized(this){
            isLockedForThisThread =
                isLocked || waitingThreads.get(0) != queueObject;
            if(!isLockedForThisThread){
              isLocked = true;
               waitingThreads.remove(queueObject);
               lockingThread = Thread.currentThread();
               return;
             }
          }
          try{
            queueObject.doWait();
          }catch(InterruptedException e){
            synchronized(this) { waitingThreads.remove(queueObject); }
            throw e;
          }
        }
    }

    public synchronized void unlock(){
        if(this.lockingThread != Thread.currentThread()){
          throw new IllegalMonitorStateException(
            "Calling thread has not locked this lock");
        }
        isLocked = false;
        lockingThread = null;
        if(waitingThreads.size() > 0){
          waitingThreads.get(0).doNotify();
        }
    }
}

public class QueueObject {

  private boolean isNotified = false;

  public synchronized void doWait() throws InterruptedException {
    while(!isNotified){
        this.wait();
    }
    this.isNotified = false;
  }

  public synchronized void doNotify() {
    this.isNotified = true;
    this.notify();
  }

  public boolean equals(Object o) {
    return this == o;
  }
}

FairLock新创建了一个QueueObject的实例,并对每个调用lock()的线程进行入队列。调用unlock()的线程将从队列头部获取QueueObject,并对其调用doNotify(),以唤醒在该对象上等待的线程。通过这种方式,在同一时间仅有一个等待线程获得唤醒,而不是所有的等待线程。

相关文章

  • 6.饥饿和公平

    饥饿 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。 导致饥饿的原...

  • 饥饿和公平

    如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。而该线程被“饥饿致死...

  • Java并发之“饥饿”和“公平锁”(Starvation and

    饥饿发生的原因: 高优先级的线程占用了大部分的cpu时间,低优先级线程发生饥饿 线程被永久堵塞在一个等待进入同步块...

  • 并发几个概念

    1.同步与异步 2.并发和并行 3.临界区 4.阻塞和非阻塞 5.死锁、饥饿、活锁 6.并发级别 6.1阻塞 6....

  • Java线程饥饿和锁的公平性「译」

    一个线程因为被其它线程抢占了而分配不到时间片,这就是【饥饿】。这个线程【饿的要死】因为只有别的线程可以得到CPU时...

  • 不幸和悲哀

    偶尔我也会叹息自己的不幸 抱怨命运的不公 可命运对谁又是公平的呢! 有时我也会为这个世界悲哀 痛恨贫穷、饥饿和战争...

  • 三月课|婚姻里必须知道的10件事 Part2

    婚姻里必须知道的十件事6.刺猬需要温柔的开场 每对夫妻每天都会遇到不同的争执和矛盾,而这些,往往都是“公平”和“尊...

  • 饥饿和贫穷

    多年前看过一篇文章,大致内容是讲自己从小就经受饥饿在三年自然灾害中又差点被饿死的母亲喜欢屯粮的故事。作者的母...

  • 2018-08-31

    ☹饥饿不想更新的一晚 饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿饥饿...

  • 2018.7.12《钢铁是怎样炼成的》第七章读后感

    保尔是一个苦孩子,他生活在社会的最底层,受压迫受欺侮,处在饥饿和死亡线上.但是,他敢于向不公平的屈辱的社会...

网友评论

      本文标题:6.饥饿和公平

      本文链接:https://www.haomeiwen.com/subject/jqtsottx.html