2016-03-08 3 views
0

Я должен сказать, что у меня есть опыт работы с потоками, и я был бы признателен, если бы кто-то мог мне помочь. У меня есть этот кусок кода, который в основном запрашивает состояние всех машин, расположенных в комнате:Код от последовательного к потоку

private List<ListRow> fetchListRows(Model amtRoomMachinesListModel) 
{ 
    Room room = RoomHelper.getRoomByDbId(...); 

    List<ListRow> listRows = new ArrayList<>(); 

    for (Machine machine : room.getRoomPCs()) 
    { 
     setMachineStatus(machine); 

     if (amtRoomMachinesListModel.getState() == null 
       || amtRoomMachinesListModel.getState().equalsIgnoreCase(machine.getState().getLabel())) 
     { 
      ListRow listRow = new ListRow(false, machine); 

      listRows.add(listRow); 
     } 
    } 

    sortListRows(listRows); 

    return listRows; 
} 


private void setMachineStatus(Machine machine) 
{ 
    State retrievedMachineState = State.ERROR; 
    String machineName = ""; 

    try 
    { 
     machineName = AMTCHelper.ip2MachineName(machine); // executes a nslookup 

     retrievedMachineState = AMTCHelper.retriveMachineState(retrievedMachineState, machineName); // executes an external C program and read the response 
    } 
    catch (IOException | InterruptedException | ParseException e) 
    { 
     throw new BRException(ExceptionType.AMTC_ERROR, "command", String.format(AMTCHelper.getRetriveMachineStateCommand(), machineName) , "error", e.getMessage()); 
    } 

    machine.setState(retrievedMachineState); 
} 

Поскольку время отклика запроса о состоянии составляет от 4 до 10 секунд, а количество машин в номер может быть более 100, я подумал, что было бы полезно использовать потоки для «одновременного» запуска процесса над списком машин, чтобы общее время процесса было разумно короче.

Я забыл сказать, что я использую java 7 (не 8).

Может кто-нибудь сказать мне, как я могу преобразовать свой последовательный код в потокобезопасный - используя его, пожалуйста?

+0

Вы пытались перебраться через 'CompletableFuture' и посмотреть, подходит ли это вашему делу? если вы чувствуете себя очень авантюрно, вы всегда можете использовать пул объектов. – svarog

+0

@svarog: Я забыл сказать, что я использую java7 ... – Francesco

+0

В Java 7 вы можете использовать пул потоков или исполнитель, java имеет несколько реализаций. – svarog

ответ

1

Как Сварог сказал, есть несколько осуществления, которые приходят с Java 7.

в java.util.concurrent, у вас есть, например, класс палач, который обеспечивает:

ExecutorService service = Executors.newFixedThreadPool(nbThreads); 

Основываясь на том, что , вы можете использовать java.util.concurrent.Future

for (Machine machine : room.getRoomPCs()) 
{ 
    Callable<State> process = new Callable<Integer>() { 
     //whatever you do to retrieve the state 
     return state; 
    } 

    // At this point, the process begins if a thread is available 
    Future<State> future = service.submit(process); 
} 

процесс выбежала на submit(). Вы можете создать таким образом список фьючерсов. Когда вы вызываете future.get(), основной поток зависает, пока вы не получите ответ.

Наконец, я предлагаю вам взглянуть на гуаву, есть много довольно полезных функций. Добавление обратного вызова (onsuccess, on error) к будущему, например.