在我的代码中,因为我可以防止由睡眠写入的模拟方法引起的饥饿问题?因为如果一个线程长时间处于睡眠状态,那么永远不会写一个你在短时间内入睡的线程
该程序由许多线程组成,这些线程不断访问类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模拟的,我真的没有写到文件,在这种情况下如何防止饥饿?
答案 0 :(得分: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
}
}