Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Простейший пример
Создание двух потоков
Управление потоками
Спрайтовая анимация
Панели с двигающимся текстом
Бегущая строка с мерцанием
Устранение мерцания
Поток для записи в файл
Контроль за выводом в файл
Чтение с сервера Web

Назад Вперед

6.8. Поток для записи в файл

В примере показано, как можно использовать многопоточность для работы с файлами в автономных приложениях Java.

Исходный текст примера

Архив проекта для Java WorkShop 2.0

Немного теории

Выполнение операций с файлами может привести к блокированию однопоточных приложений на значительное время. Особенно это сказывается при работе с файлами большого объема или с файлами, расположенными на удаленном сервере в сети Internet.

Для исключения блокировки, а также для распараллеливания работы такие операции имеет смысл выполнять в отдельном потоке.

Чтобы основной поток мог контролировать работу вспомогательного потока, созданного для выполнения операций над файлами, вы должны использовать средства синхронизации потоков, предусмотренных в Java.

В этом примере мы применили простейшее средство - метод join. С его помощью основной поток может дождаться завершения порожденного потока и затем продолжить свою работу. Заметим, что ожидание, выполняемое методом join, не приводит к непроизводительной загрузке процессора, так как во время ожидания соответствующий поток не выполняется.

Описание примера

Наш пример является автономным консольным приложением Java.

Сразу после запуска он запрашивает через консоль количество блоков для записи в файл (рис. 1).

pic1.gif (3926 bytes)

Рис. 1. Работа приложения

Далее приложение запускает поток, который создает файл с именем testfile.txt и записывает в него столько строк "Test string", сколько блоков было указано в ответ на приглашение Enter number of blocks. Содержимое файла вы можете проверить при помощи любого текстового редактора.

Рассмотрим исходный текст примера.

Главный класс

Главный класс нашего примера реализует интерфейс Runnable, что необходимо для работы с потоком:

import java.io.*;
import java.util.*;

public class FileWriter
  implements Runnable
{
  . . .
}

В классе определено единственное поле nBlocks, хранящее введенное значение для количества записываемых блоков:

int nBlocks = 0;

Метод main

Этот метод получает управление сразу после запуска приложения.

Прежде всего он создает объект класса FileWriter, то есть главного класса приложения:

FileWriter fw = new FileWriter();

Далее метод выводит на консоль приглашение для ввода количества блоков:

System.out.println(
    "*Multithread file writer*\r\n");
System.out.print("Enter number of blocks: ");

Ввод числа с клавиатуры выполняется с использованием метода getKbdInt, определенного в нашем приложении:

fw.nBlocks = getKbdInt();

После ввода метод main создает поток ioThread и сразу запускает его на выполнение:

Thread ioThread = new Thread(fw);
ioThread.start();

Задача потока - создание файла и запись в него данных.

Чтобы дождаться завершения процедуры записи, основной поток (то есть метод main) вызывает метод join:

try
{
  ioThread.join();
}
catch(InterruptedException ie)
{
  System.out.println(ie.toString());
}  

Так как во время выполнения этого метода возможно возникновение исключения InterruptedException, мы предусмотрели соответствующий обработчик.

Как только работа потока будет завершена, метод main выводит соответствующее сообщение и ожидает ввода с консоли любого символа:

System.out.print(
  "All done!\r\nPress <Enter>...");
getKbdByte();

Метод run

Метод run работает в отдельном потоке.

Сразу после запуска он создает поток ввода/вывода класса DataOutputStream:

DataOutputStream os;
    
try
{
  os = new DataOutputStream(
    new FileOutputStream("testfile.txt"));
    
  for(int i = 0; i < nBlocks; i++)
  {
    os.writeBytes("Test string\r\n");
  }
    
  os.flush();
  os.close();
}
catch(Exception ioe)
{
  System.out.println(ioe.toString());
}

Затем метод записывает в этот поток ввода/вывода nBlocks текстовых строк, сбрасывает буферы потока и закрывает поток методом close.


Назад Вперед

[Назад]