首页 文章

饥饿线程

提问于
浏览
-1

在我的代码中,我可以防止由睡眠写入的模拟方法引起的饥饿问题?因为如果一个线程长时间处于休眠状态,那么永远不会写一个你在短时间内入睡的线程

该程序由许多线程组成,这些线程不断访问类my_file的write方法,该实例由所有线程共享,但一次只有一个线程可以写入该文件 .

public class My_File {

  private boolean writing = false;

  public synchronized void write() { 
    String name = Thread.currentThread().getName();
    System.out.println(name +" writing ");
    try{
        Thread.sleep((int)(Math.random()*3000));
    } catch( InterruptedException e){
        e.printStackTrace();
    }
    System.out.println(name +" writing end ");
  }   
}

我有这个问题,我有很多线程共享的文件很多,所有线程什么都不做但是在这种情况下尝试写入文件,写入是通过方法sleep模拟的,我真的没有写入文件,在这种情况我怎样才能防止饥饿?

1 回答

  • 1

    您需要一个公平的重入锁定来保证一致的吞吐量 . 您的情况与错误描述中的Logback错误268非常相似:

    “简单”同步“锁定不保证通过等待线程获取锁定的顺序,因此,有时,”最后输入“线程获取锁定,而”第一次进入“线程可能会等待很长时间......”

    “我试图用”公平“模式下的java.util.concurrent.locks.ReentrantLock替换这个锁,情况有了很大改善!

    代码更改显示在github commit中 . 在伪代码中,更改此模式:

    class MyFileUnfair {
    
        private final Object writeLock = new Object();
    
        public void write(byte[] data) {
    
            synchronized(writeLock) {
                writeToFile(data); 
            }
        }
    
        private void writeToFile(byte[] data) {
            // write to file
        }
    }
    

    对于这种模式:

    class MyFileFair {
    
        private final ReentrantLock writeLock = new ReentrantLock(true);
    
        public void write(byte[] data) {
    
            writeLock.lock();
            try {
                writeToFile(data);
            } finally {
                writeLock.unlock();
            }
        }
    
        private void writeToFile(byte[] data) {
            // write to file
        }
    }
    

相关问题