Основы Java Threading

В чем разница между двумя потоковыми вызовами ниже? Будут ли два вызова действовать одинаково?

ПРИМЕЧАНИЕ. Я не использую одновременно # 1 и # 2, что является лучшим вариантом.

private void startConnections(){
 ServerThread server = new ServerThread();
 server.start(); // #1
 Thread serverThread = new Thread(server);
 serverThread.start(); //#2
}
class ServerThread extends Thread{
 public void run(){}
}
1 ответ

Первый подход является приемлемым, но не рекомендуется. Второй работает, но сломан/трудно понять. Рассмотрим третий:

class ServerRunnable implements Runnable {
 public void run(){}
}
Runnable run = new ServerRunnable();
Thread serverThread = new Thread(run);
serverThread.start(); //#3

# 1

Это довольно распространенный подход - для создания нового потока вы просто подклассифицируете его и вызываете метод start(). Многие люди, в том числе и я, считают эту идиому плохой практикой - она ​​необязательно связывает задачу (содержание метода run()) с потокованием (Thread class).

# 2

Я никогда не видел такой код и хотя технически работал, я бы исправил его немедленно. Даже при том, что вы создаете экземпляр потока, вы передаете его другому потоку и начинаете его. Итак, зачем создавать первый поток на первом месте? Обратите внимание, что Thread также реализует Runnable, поэтому он технически работает, но действительно неудобен.

# 3

Так что я рекомендую? Внедрите интерфейс Runnable, который не связан с потоками. Вы не можете запускать Runnable только в отдельном потоке, вы должны явно создать этот поток. Но наличие raw Runnable также позволяет вам легко переключаться с собственного потока на, например, пул потоков.

Технически вы можете расширить Thread и поместить такой "runnable" в пул потоков, но это действительно сложно понять, и вы также без необходимости нести багаж Thread (это довольно большой класс).

licensed under cc by-sa 3.0 with attribution.