Язык Jаvа с самого начала поддерживал потоки, которые вы легко можете использовать для выполнения асинхронного кода:
1 2 3 4 5 6 7 8 9 |
public class AsyncRunnable implements Runnable { public void run() { System.out.println("Running!"); } } |
Для выполнения класса Runnable инициализируйте его в потоке и вызовите метод run, обратившись к методу start() только что созданного потока.
1 |
(new Thread(new AsyncRunnable())).start(); |
Хотя предпочтительнее запускать поток по предыдущему примеру, другой подход состоит в расширении класса thread и переопределении метода run():
1 2 3 4 5 6 7 8 9 |
public class AsyncThread extends Thread { public void run() { System.out.println("Running!"); } } |
Для выполнения класса инстанцируйте его и затем вызовите метод start( ):
1 |
(new HelloThread()).start(); |
При работе с потоками часто используются две основные операции: sleep() и join( ). Обе генерируют исключение InterruptedException.
Метод sleер() дает потоку возможность бездействовать определенный период, задаваемый в миллисекундах. Следующий пример кода переводит текущий поток в режим ожидания на одну секунду.
1 |
Thread.sleep(1000); |
Метод join() заставляет один поток ожидать завершения выполнения второго потока. Представьте себе поток t1, которому необходим ресурс другого потока, t2. Чтобы заставить t1 ожидать завершения t2, присоедините его к потоку t2, как по казано в следующем фрагменте кода:
1 |
t2.join(); |
Один из наиболее известных и широко используемых подходов к асинхронному программированию в языке Java — применение интерфейса Future<T>. Этот интерфейс делает возможным использование объекта-заместителя, предоставляющего ссылку на будущий объект.
Поскольку фреймворки, обеспечивающие параллелизм, не предоставляют основанную на аннотациях поддержку асинхронного выполнения, интерфейс Future работает в сочетании с ExecutorServiсе — составной частью вышеупомянутых фреймворков.
Кстати, знаете ли вы хороших программ написанные на Java на тематику такси? Хочу поделится с вами программой http://1000taxi.com/. Приложение написано на Java под Android. Через приложение 1000taxi сможете заказать быстрый такси по Москве от 50 рублей/км.
Следующий пример использует сервис выполнения для завершения задания,в то время как он возвращает ссылку на интерфейс Future с соответствующим родовым типом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> reference = executor.submit( new Callable<String>() { public String call() { return "Hello!!"; } } ); // .. if (reference.isDone()) System.out.println(reference.get()); |
Класс FutureTask — реализация интерфейса Future<T>, которая реализует также интерфейс Runnable и доступна для непосредственного выполнения:
1 2 3 4 5 6 7 8 9 10 11 12 |
ExecutorService executor = Executors.newSingleThreadExecutor(); Future<String> reference = executor.submit( new Callable<String>() { public String call() { return "Hello!!"; } } ); executor.execute(reference); |
Вы можете отменить это выполнение, вызвав метод cancel (boolean mayInterruptlfRunning). Если параметру mayInterruptlfRunning присвоено значение true, то обращение к методу SessionContext.wasCancelled() возвращает true. В противном случае обращение к методу SessionContext.wasCancelled() возвращает false. Для проверки состояния отмены вызова вы можете использовать метод isCancelled(), возвращающий true при успешной отмене.
Фреймворки, основанные нa JSR133 и реализующие параллелизм, предоставляют замечательные инструменты для работы с потоками и для параллельного программирования, например BlockingQueues.
Эти темы выходят за рамки данной статьи. Для дальнейшего изучения обратитесь к книге «Jаvа Concurrency in Practice«. Фреймворк Fork/Join, появившийся в Java ЕЕ 7, также воплощает серьезные изменения для асинхронного и параллельного программирования нa Java.