2014-02-07 3 views
2

Я пытаюсь записать файл. Мне нужно иметь возможность «добавлять» к файлу, а не писать поверх него. Кроме того, мне нужно, чтобы он был потокобезопасным и эффективным. Код, который у меня есть в настоящее время:Безопасность потоков PrintStream в Java

private void writeToFile(String data) { 
    File file = new File("/file.out"); 
    try { 
     if (!file.exists()) { 
     //if file doesnt exist, create it 
     file.createNewFile(); 
     } 
     PrintStream out = new PrintStream(new FileOutputStream(file, true)); 
     DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 
     Date date = new Date(); 
     out.println(dateFormat.format(date) + " " + data); 

     out.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 

Все работает отлично. Я просто не знаю, является ли PrintStream потокобезопасным или нет. Итак, мой вопрос: Является ли запись в тот же физический файл из нескольких экземпляров PrintStream безопасным? Если да, использует ли он блокировку (снижает производительность) или очереди? Знаете ли вы о каких-либо родных java-библиотеках, которые являются потокобезопасными и используют очередь? Если нет, у меня нет проблем писать свои собственные. Я просто пытаюсь понять, есть ли что-нибудь родное, прежде чем я напишу свой собственный.

+0

'Методы PrintStream'' синхронизированы'. Очередь осуществляется через буфер записи. –

+3

Безопасность нитей PrintStream сама по себе не имеет значения в вашем случае, поскольку вы получаете доступ только через локальный экземпляр. Вы хотели спросить, безопасно ли писать один и тот же физический файл из нескольких экземпляров PrintStream? – assylias

+0

@assylias да. Спасибо за исправление. Я отредактирую свой вопрос, чтобы представить это. –

ответ

3

Источник PrintStream предполагает, что он является потокобезопасным.

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

/** 
* Prints a String and then terminate the line. This method behaves as 
* though it invokes <code>{@link #print(String)}</code> and then 
* <code>{@link #println()}</code>. 
* 
* @param x The <code>String</code> to be printed. 
*/ 
public void println(String x) { 
    synchronized (this) { 
     print(x); 
     newLine(); 
    } 
} 
+0

блокировка для каждого экземпляра - вопрос включает несколько экземпляров. – assylias

+0

Это идея, которую я продумал, но если я это сделаю, будет ли она использовать блокировку или очередность? –

+0

@assylias Извините, не было ясно, что OP хотел, чтобы несколько экземпляров записывали в тот же файл в начале. Но теперь, когда это ясно, мне интересно, есть ли хорошая идея иметь несколько экземпляров, записывающих один файл. Каковы преимущества этого по сравнению с одним экземпляром, разделяемым между различными потоками? – anonymous