我遇到一些问题,理解为什么当我多次创建一个实现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
方法,因此我会进行所需的验证。
答案 0 :(得分:2)
如果使用Runnable
接口,则Java多线程中没有执行顺序。无法保证articulo1
将在articulo2
之前完成。
@Test
的问题:它在一个单独的线程上运行,因此测试方法在Runnable
完成之前很久就会完成。
我建议您真正阅读Oracle网页上的官方Concurrency路径。
答案 1 :(得分:-1)
我不确定我是否理解你的问题,但你不能保证线程中的某个顺序,除非你使用某种旗帜。
这可能不是最好的解决方案,但如果要将它应用于小型项目,它可以为您服务。
例如,您可以使用全局/静态变量或join or countdownlatches
之类的可用结构来实现此目的。
希望它对你有所帮助! :)