多线程执行顺序

时间:2015-04-28 14:35:49

标签: java multithreading

我遇到一些问题,理解为什么当我多次创建一个实现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()); } } } 1}}然后它就是对象的运行方法。

以下是代码:

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();
        }
    }

}

和GuardarArticulos班级:

starts()

我期待的是,在我调用所有@Test后,它会从线程开始,然后完成运行def to_liquid(attrs = nil) date_format = self.site.config['date_format'] new_datas = { "title" => self.data['title'] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '), "url" => self.url, "date" => self.date, # Monkey patch "date_formatted" => format_date(self.date, date_format), "updated_formatted" => self.data.has_key?('updated') ? format_date(self.data['updated'], date_format) : nil, "id" => self.id, "categories" => self.categories, "next" => self.next, "previous" => self.previous, "tags" => self.tags, "content" => self.content } Utils.deep_merge_hashes(self.data, new_datas) end 方法,因此我会进行所需的验证。

2 个答案:

答案 0 :(得分:2)

如果使用Runnable接口,则Java多线程中没有执行顺序。无法保证articulo1将在articulo2之前完成。

@Test的问题:它在一个单独的线程上运行,因此测试方法在Runnable完成之前很久就会完成。

我建议您真正阅读Oracle网页上的官方Concurrency路径。

答案 1 :(得分:-1)

我不确定我是否理解你的问题,但你不能保证线程中的某个顺序,除非你使用某种旗帜。

这可能不是最好的解决方案,但如果要将它应用于小型项目,它可以为您服务。

例如,您可以使用全局/静态变量或join or countdownlatches之类的可用结构来实现此目的。

  1. 让我们看一个名为“A”的静态变量的例子。
  2. 每次创建新线程时,都会增加名为“B”的变量 并将该变量值作为参数传递给新线程。
  3. 如果值传递,则thread.B等于静态变量A. 是时候运行线程,增加静态变量A in 结束。
  4. 如果thread.B不等于A,则线程等待A为 等于B。
  5. 希望它对你有所帮助! :)