Пример потока Java
Добро пожаловать в пример потока Java. Процесс и поток — две основные единицы выполнения. Параллельное программирование больше связано с потоками Java.
Процесс
Процесс — это автономная среда выполнения, и его можно рассматривать как программу или приложение. Однако сама программа содержит внутри себя несколько процессов. Среда выполнения Java работает как единый процесс, который содержит различные классы и программы в качестве процессов.
Нить
Поток можно назвать облегченным процессом. Поток требует меньше ресурсов для создания и существует в процессе, поток разделяет ресурсы процесса.
Пример потока Java
Преимущества потоков Java
- Потоки Java проще по сравнению с процессами, для создания потока требуется меньше времени и ресурсов.
- Потоки обмениваются данными и кодом родительского процесса
- Переключение контекста между потоками обычно дешевле, чем между процессами.
- Взаимодействие потоков относительно проще, чем взаимодействие процессов.
Java предоставляет два способа программного создания потока.
- Реализация интерфейса java.lang.Runnable.
- Расширение класса java.lang.Thread.
Пример потока Java - реализация интерфейса Runnable
Чтобы сделать класс работоспособным, мы можем реализовать интерфейс java.lang.Runnable и предоставить реализацию в методе public void run()
. Чтобы использовать этот класс в качестве потока, нам нужно создать объект потока, передав объект этого исполняемого класса, а затем вызвать метод start()
для выполнения метода run()
в отдельная ветка. Вот пример java-потока с реализацией интерфейса Runnable.
package com.journaldev.threads;
public class HeavyWorkRunnable implements Runnable {
@Override
public void run() {
System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
//Get database connection, delete unused data from DB
doDBProcessing();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
}
private void doDBProcessing() throws InterruptedException {
Thread.sleep(5000);
}
}
Пример Java Thread - расширение класса Thread
Мы можем расширить класс java.lang.Thread, чтобы создать собственный класс потока Java и переопределить метод run()
. Затем мы можем создать его объект и вызвать метод start()
для выполнения нашего пользовательского метода запуска класса потока Java. Вот простой пример потока Java, показывающий, как расширить класс Thread.
package com.journaldev.threads;
public class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("MyThread - START "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
//Get database connection, delete unused data from DB
doDBProcessing();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("MyThread - END "+Thread.currentThread().getName());
}
private void doDBProcessing() throws InterruptedException {
Thread.sleep(5000);
}
}
Вот тестовая программа, показывающая, как создать поток Java и выполнить его.
package com.journaldev.threads;
public class ThreadRunExample {
public static void main(String[] args){
Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
System.out.println("Starting Runnable threads");
t1.start();
t2.start();
System.out.println("Runnable Threads has been started");
Thread t3 = new MyThread("t3");
Thread t4 = new MyThread("t4");
System.out.println("Starting MyThreads");
t3.start();
t4.start();
System.out.println("MyThreads has been started");
}
}
Вывод приведенной выше примерной программы java-потока:
Starting Runnable threads
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - START t2
Starting MyThreads
MyThread - START Thread-0
MyThreads has been started
MyThread - START Thread-1
Doing heavy processing - END t2
MyThread - END Thread-1
MyThread - END Thread-0
Doing heavy processing - END t1
Как только мы запускаем любой поток, его выполнение зависит от реализации квантования времени в ОС, и мы не можем контролировать их выполнение. Однако мы можем установить приоритет потоков, но даже в этом случае это не гарантирует, что поток с более высоким приоритетом будет выполнен первым. Запустите приведенную выше программу несколько раз, и вы увидите, что нет шаблона начала и конца потоков.
Runnable против потока
Если ваш класс предоставляет больше функциональных возможностей, а не просто работает как Thread, вам следует реализовать интерфейс Runnable, чтобы обеспечить способ запуска его как Thread. Если единственная цель вашего класса — работать как Thread, вы можете расширить класс Thread. Реализация Runnable предпочтительнее, потому что java поддерживает реализацию нескольких интерфейсов. Если вы расширяете класс Thread, вы не можете расширять какие-либо другие классы. Совет: Как вы заметили, этот поток не возвращает никакого значения, но что, если мы хотим, чтобы наш поток выполнял некоторую обработку, а затем возвращал результат нашей клиентской программе, проверьте наши функциональные интерфейсы Java 8.