2015-04-28 2 views
1

У меня возникли проблемы с пониманием того, почему, когда я создаю объект несколько раз, который реализует интерфейс runnable, и я создал их на @Test, когда я вызываю эти объекты start(), он запускает сначала @Test, а затем он запускать метод, если объекты.Порядок выполнения нескольких нитей

Вот код:

public class Tests extends { 
    @Test(testName = "754") 
    public void concurrenciaGuardarArticuloTMP() throws Exception { 
     try { 
      this.codigoBarras =this.generarCodigoDeBarra(); 
      System.out.println(codigoBarras); 
      logger.info("Codigo de barras generado fue ::: " + codigoBarras); 
      GuardarArticuloTMP articulo1 = new GuardarArticuloTMP(GuardarArticuloTMP.TMP.TMP_CODIGO_BARRA,"TMP, Hilo 1", codigoBarras,35); 
      GuardarArticuloTMP articulo2 = new GuardarArticuloTMP(GuardarArticuloTMP.TMP.TMP_CODIGO_BARRA,"TMP, Hilo 2", codigoBarras,37); 
       articulo1.start(); 
      articulo2.start(); 
      logger.info("Codigo de barras generado fue ::: " + codigoBarras); 
      System.out.println("Codigo de barras generado fue ::: " + codigoBarras); 
      logger.info(writeDTO(articulo1.getArticulo())); 
     } catch (Exception ex) { 
      logger.error("Error guardando Articulo.", ex); 
      this.setExecutionDetail(ex.getMessage()); 
     } 
    } 
} 

И GuardarArticulos Класс:

public class GuardarArticuloTMP extends Setup implements Runnable{ 

    private Thread t; 
    private String threadName; 
    private String codigoBarras; 
    private int numeroCaja; 
    private static Logger logger = Logger.getLogger(GuardarArticulo.class); 

    /** 
    * @param pThreadName nombre del hilo 
    * @param pCodigoBarras codigo de barras 
    * @param pNumeroCja numero de caja para el local 
    */ 
    public GuardarArticuloTMP(TMP tmp, String pThreadName, String pCodigoBarras, int pNumeroCja) { 
     this.threadName = pThreadName; 
     this.codigoBarras = pCodigoBarras; 
     this.numeroCaja = pNumeroCja; 
     this.tmp = tmp; 
     initLogger(); 
    } 

    /** 
    * Crea un articulo 
    * @return nos devuelve un articulo 
    * @throws Exception 
    */ 
    private ArticuloFacadeDTO crearArticulo() throws Exception { 
     //creates Articulo 
     return toSave; 
    } 

    @Override 
    public void run() { 
     System.out.println("Corriendo " + this.threadName.toUpperCase() + " !!!!!!!!!!!!!!!!!!!!!!!!"); 
     logger.info("Corriendo " + this.threadName.toUpperCase() + " !!!!!!!!!!!!!!!!!!!!!!!!"); 
     try{ 
      Thread.sleep(50); 
      logger.info("estoy en el run por crear el articulo"); 
      ArticuloFacadeDTO toSave = crearArticulo(); 
      writeDTO(toSave); 
      mgr.guardarArticuloFacade(toSave); 
      Thread.sleep(50); 
     }catch(Exception ex) { 
      ex.printStackTrace(); 
      logger.error("Error::: ",ex); 
     } 
    } 

public void start() 
    { 
     logger.info("Empezado el thread " + this.threadName); 
     if (t == null) { 
      t = new Thread (this, threadName); 
      t.setPriority(10); 
      t.start(); 
     } 
    } 

} 

Что я ожидаю, что после того, как я называю все starts(), он начинает на резьбе затем завершении сеанса @Test, поэтому я делаю необходимые проверки.

+1

Вы не описали фактическую проблему, с которой вы сталкиваетесь, и не включаете реализацию метода start(). – jtahlborn

+2

Извините, я не могу понять, в чем проблема. Мне кажется, что у вас могут быть некоторые неправильные представления о том, как многопоточность работает в java. Не могли бы вы уточнить? – Tavo

+0

Вы указываете, что ожидаете, но не указываете, что на самом деле делала программа. Начали ли темы? –

ответ

2

В Java многопоточность нет, если вы используете интерфейс Runnable. Нет гарантии, что articulo1 закончит до articulo2.

Проблема с @Test: она работает по отдельной теме, поэтому метод тестирования заканчивается задолго до окончания вашего Runnable.

Я предлагаю вам действительно прочитать официальный маршрут Concurrency на веб-странице Oracle.

+0

спасибо, не знал, что @Test работает на отдельных потоках – elcharrua

-1

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

Это, вероятно, не лучшее решение, но если оно применяется на небольшом проекте, оно может служить вам.

Например, вы можете использовать переменную Global/Static или доступные конструкции, такие как join or countdownlatches, чтобы сделать это.

  1. Посмотрите пример со статической переменной, называемой «A».
  2. Каждый раз, когда вы создаете новый поток, увеличивайте переменную с именем «B» и передайте это значение переменной в качестве аргумента в новый поток.
  3. Если значение передано, поток.B равен статической переменной A, тогда пришло время запускать поток, увеличивая статическую переменную A в конца.
  4. Если thread.B не равен А, то поток ожидает, чтобы быть равна B.

Надеется, что это помогает! :)

+2

Как вы думаете, как вы можете заказать исполнение с использованием статической переменной? Можете ли вы объяснить это? – Arkantos

+0

Статическая переменная называется «А». Каждый раз, когда он создает новый поток, он увеличивает переменную с именем «B» и передает это значение переменной в качестве аргумента в новый поток. Если значение B внутри потока равно статической переменной A, тогда пришло время запустить его, и в конце он увеличит статическую переменную. Если он не равен, то поток ожидает, что переменная A будет равна B. Пожалуйста, исправьте меня, если я полностью ошибаюсь! :) –

+2

Ну, ваша идея хорошая, но когда вы ее реализуете, вы увидите, что статический не такой хороший выбор, вам нужно синхронизировать доступ к статической переменной, чтобы он работал в соответствии с вашими ожиданиями, но в нем есть проблема обсуждение разногласий. Кроме того, вам необходимо убедиться, что вы всегда читаете обновленную статическую переменную, необходимо запустить цикл, чтобы проверить обновление переменной и действовать на нее. Это немного сложно, но если вы правильно используете 'volatile' и' atomics', вы можете это сделать :) Но вместо того, чтобы повторно изобретать колесо, вы можете просто использовать существующие конструкции, такие как 'join или countdownlatches' – Arkantos

Смежные вопросы