Существует два способа определить поведение потока: создать подкласс класса Thread или реализовать интерфейс Runnable.
Для первого способа просто расширьте класс Thread и переопределите метод run () в собственной реализации:
public class HelloThread extends Thread {
@Override
public void run() {
System.out.println("Hello from a thread!");
}
}
public class Main {
// main method just starts the thread
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Однако предпочтительным способом реализации логики для потока является создание класса, реализующего интерфейс Runnable:
public class HelloRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hello from a thread!");
}
}
public class Main {
// notice that we create a new Thread and pass it our custom Runnable
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Причина, по которой реализация Runnable является предпочтительной, заключается в том, что она обеспечивает четкое разделение между поведением потока и самого потока. Например, при использовании пула потоков вы фактически никогда не создаете поток с нуля, вы просто передаете Runnable в платформу и он выполнит его в доступном для вас потоке:
public class Main {
public static void main(String args[]) {
int poolSize = 5;
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
pool.execute(new HelloRunnable());
}
}
Дополнительная литература: