2014-11-25 5 views
-1

В моем коде, поскольку я могу предотвратить проблему голодания, вызванную методом симуляции написания со сном? Потому что если поток поспать долгое время, он никогда не будет писать, чем тот, который вы спали в течение короткого времени.Головоломка

Программа состоит из множества потоков, которые постоянно обрабатывают метод записи класса my_file, экземпляр которого разделяется всеми потоками, но только один поток за раз может записать в файл.

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 "); 
    } 
} 

У меня есть эта проблема, у меня есть много файлов, разделяемых многие нити, все нити, которые ничего не делают, но стараются писать в файл в случае, запись моделируются сном метода, я не действительно пишите в файл, в этой ситуации, как я могу предотвратить голод?

+0

Вы должны изменить этот вопрос, как в его поддаются интерпретации текущей формы. Кстати, не используйте ключевое слово 'synchronized', поскольку оно обычно небезопасно, и в большинстве других случаев оно не обязательно, но неэлегантно. – Powerslave

+0

Что я могу использовать вместо синхронизации? То, что не ясно ? – alexander

+0

Я не уверен, какова ваша проблема/вопрос, поскольку слова кажутся близкими к случайным. Вместо использования 'synchronized', вы могли бы, например, обернуть логгер (я полагаю, что вы используете фреймворк регистрации, а не собственную реализацию регистратора) в классе с' BlockingDeque' и имеете выделенный поток журналов, возглавляющий очереди и передать его в журнал. 'BlockingDeque' является потокобезопасным, поскольку он всегда блокируется, когда он заполнен. Если попытка ведения журнала отключена, просто повторите попытку. Кроме того, существуют и другие параллельные коллекции или решения. – Powerslave

ответ

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 
    } 
} 
Смежные вопросы