Возможно ли вернуть переданный в Thread объект?
Например, передали объект Cats в Thread:
static List<Thread> threads = new ArrayList<Thread>(3);
void initThreads() {
Cats cat = new Cats("cat");
for (int i = 0; i < 3; i++) {
threads.add(new Thread(cat, "#" + i));
}
}
Можно вернуть объект Cats из threads[i]?
Ответы (2 шт):
Автор решения: lampa
→ Ссылка
Смотря что с котом будет происходить) Если нужно просто вернуть объект Cats, а у вас Cats это похоже что Runnable, то без танцев с бубном не получится получить Runnable из Thread. Варианты, например, через Map или рефлексию:
Map<Thread, Runnable> cats = new HashMap<>();
void initThreads() {
Cats cat = new Cats("cat");
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(cat, "#" + i);
cats.put(thread, cat);
}
}
...
cats.get(thread).getName();
Или если не хочется мапу, но такое лучше не использовать:
Thread thread = new Thread(new Cat("cat"), "123");
Field runnable = thread.getClass().getDeclaredField("runnable");
runnable.setAccessible(true);
Cat cat = (Cat) runnable.get(thread);
А если хочется дождаться результата, то нужно действовать по другому:
ExecutorService catExecutor = Executors.newSingleThreadExecutor();
List<Future<Cat>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
final int index = i;
final Future<Cats> future = catExecutor.submit(new Callable<Cat>() {
@Override
public Cats call() throws Exception {
Thread.sleep(...);
return new Cat("cat " + index);
}
});
futures.add(future);
}
for (Future<Cats> f : futures) {
try {
System.out.println(f.get().getName());
} catch (InterruptedException | ExecutionException ex) {
ex.printStackTrace();
}
}
Автор решения: Anastasiya
→ Ссылка
- Имплементировать для
CatинтерфейсRunnable:
public class Cat implements Runnable {
private String name;
//getters setters constructor
@Override
public void run() {
//some logic...
}
}
- Понасоздавать экземпляров сколько влезет и подобавлять в список:
List<Cat> cats = IntStream.range(0, 3)
.mapToObj(i -> new Cat("name#" + i))
.collect(Collectors.toList());
- Создать экземпляр
executorServiceи запустить каждый поток:
ExecutorService service = Executors.newCachedThreadPool();
cats.forEach(service::execute);
И все, пока они выполняются можете что-нибудь поделать с этим списком, например:
cats.stream()
.map(Cat::getName)
.forEach(System.out::println);
//Output: cat names...